zoukankan      html  css  js  c++  java
  • 竞赛基础篇---部分和问题(DFS)

    问题链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=1058

    描述
    给定整数a1、a2、.......an,判断是否可以从中选出若干数,使它们的和恰好为K。
     
    输入
    首先,n和k,n表示数的个数,k表示数的和。
    接着一行n个数。
    (1<=n<=20,保证不超int范围)
    输出
    如果和恰好可以为k,输出“YES”,并按输入顺序依次输出是由哪几个数的和组成,否则“NO”
    样例输入
    4 13
    1 2 4 7
    样例输出
    YES
    2 4 7
    思路:
    直接dfs,每次dfs用两个参数,一个为当前层数,一个为当前以及凑出的总和。这里可以剪枝:如果当前凑出的总和 > k,直接返回false;
    此处还应该记录每个数字是否被标记,这里需要注意,一定要在返回真之后再加标记,因为只有返回真,才能确定该点的标记状态
     1 #include<iostream>
     2 #include<string>
     3 #include<vector>
     4 #include<cstdio>
     5 #include<cstring>
     6 #define FOR(i, a, b) for(int i = a; i < b; i++)
     7 using namespace std;
     8 int n, k;
     9 int a[50], vis[50]; 
    10 bool dfs(int d, int tot)
    11 {
    12     if(tot > k)return false;
    13     if(d == n)return tot == k;//到了最后一层,直接返回判断结果 
    14     //如果第i层不放a[i]
    15     if(dfs(d + 1, tot))
    16     {
    17         vis[d] = 0;//标记未放 
    18         return true;
    19     } 
    20     //如果第i层放a[i] 
    21     if(dfs(d + 1, tot + a[d]))
    22     {
    23         vis[d] = 1;//标记已放 
    24         return true;
    25     }
    26     return false;
    27 }
    28 int main()
    29 {
    30     while(cin >> n >> k){
    31     for(int i = 0; i < n; i++)
    32     {
    33         cin >> a[i];
    34     }
    35     if(dfs(0, 0))
    36     {
    37         printf("YES
    ");
    38         for(int i = 0; i < n; i++)if(vis[i])printf("%d ", a[i]);
    39         printf("
    ");
    40     }
    41     else
    42         printf("NO
    ");
    43     }
    44     return 0;
    45 }
    NOIP普及组、提高组培训,有意可加微信fu19521308684
  • 相关阅读:
    这是一篇通过open live writer发布的博文
    网卡重启失败
    2020年1月目标
    二、安装docker
    JS中的数据类型,包含ES6,set和map等等
    关于prototype和__proto__,最好的一些解释
    JS中call,apply和bind方法的区别和使用场景
    ThinkPHP5生成word文档代码库
    js/jquery操作iframe
    PHP技术--思维导图
  • 原文地址:https://www.cnblogs.com/fzl194/p/8672217.html
Copyright © 2011-2022 走看看