• 蓝桥杯 盾神与砝码称重 dfs 剪枝


    问题描述
      有一天,他在宿舍里无意中发现了一个天平!这个天平很奇怪,有n个完好的砝码,但是没有游码。盾神为他的发现兴奋不已!于是他准备去称一称自己的东西。他准备好了m种物品去称。神奇的是,盾神一早就知道这m种物品的重量,他现在是想看看这个天平能不能称出这些物品出来。但是盾神稍微想了1秒钟以后就觉得这个问题太无聊了,于是就丢给了你。
    输入格式
      第一行为两个数,n和m。
      第二行为n个数,表示这n个砝码的重量。
      第三行为m个数,表示这m个物品的重量。
    输出格式
      输出m行,对于第i行,如果第i个物品能被称出,输出YES否则输出NO。
    样例输入
    4 2
    1 2 4 8
    15 16
    样例输出
    YES
    NO
    样例输入
    4 1
    10 7 1 19
    6
    样例输出
    YES
    数据规模和约定
      1<=n<=24, 1<=m<=10.
    每个砝码有三种情况。
    1:不使用这个砝码。
    2:将这个砝码和物品放在同一侧。
    3:将这个砝码放在物品另一侧。
    这道题目不优化剪枝会超时。
    可以先自己试着写一个朴素代码,然后再看如何优化更容易理解。
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int n, m;
     4 int fm[30]; //fm[i]表示第i个砝码的重量
     5 int sum[30]; //sum[i]表示前i个砝码重量和
     6 bool flag;
     7 void dfs(int x, int len) { //x:当前要测量的物品重量,len:当前可用前len个砝码去称
     8     //如果还有可用砝码并且没称出当前重量并且备选砝码重量和大于等于当前要测的重量
     9     if (len >= 1 && flag == false && abs(x) <= sum[len]) {
    10         if (abs(x) == fm[len]) {
    11             flag = true;
    12         } else {
    13             //递归的顺序对运行时间有影响
    14             dfs(x - fm[len], len - 1); //把fm[len]这个砝码放在物品的另一侧
    15             dfs(x, len - 1); //不使用fm[len]这个砝码
    16             dfs(x + fm[len], len - 1); //把fm[len]这个砝码放在物品同侧
    17         }
    18     }
    19 }
    20 int main() {
    21     cin >> n >> m;
    22     for (int i = 1; i <= n; i++) {
    23         cin >> fm[i];
    24     }
    25     sort(fm + 1, fm + 1 + n); //对砝码重量排序
    26     sum[0] = 0; //计算前n个砝码总和
    27     for (int i = 1; i <= n; i++) {
    28         sum[i] = sum[i - 1] + fm[i];
    29     }
    30     while (m--) {
    31         flag = false;
    32         int x;
    33         cin >> x;
    34         dfs(x, n); //开始搜索。现在要测量的物品重量为x,现在可用的砝码个数是n个
    35         if (flag) {
    36             cout << "YES" << endl;
    37         } else {
    38             cout << "NO" << endl;
    39         }
    40     }
    41     return 0;
    42 }

     2020年10月22日更新:感谢评论区大佬@ qdu_yyh的指正

    现在14行和16行的注释已更正

  • 相关阅读:
    entrySet()
    DBCC DBREINDEX重建索引提高SQL Server性能
    ASP中调用存储过程、语法、写法-sql server数据
    这个月一直很忙,没时间写点心得,就放点周末去玩的照片吧
    JQuery 中,使文本框获得焦点的方法
    数据库系统不能自动删除备份的原因之一
    C# 中的常用正则表达式总结
    删除在建表时SQL SERVER2000指定PRIMARY KEY引起的 聚合索引
    IIS7入门之旅:(1)appcmd命令的使用
    IIS7入门之旅:(2)如何实现和加载自定义的Basic Authentication模块
  • 原文地址:https://www.cnblogs.com/fx1998/p/12734817.html
Copyright © 2020-2023  润新知