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
  • 相关阅读:
    MFC
    AC自动机
    KMP
    Power Transmission (Hard Edition)
    Floyd
    地杰斯特算法
    二叉树
    51nod 1002 数塔取数问题【dp】
    51nod1049 最大子段和【动态规划】
    poj2385
  • 原文地址:https://www.cnblogs.com/fzl194/p/8672217.html
Copyright © 2011-2022 走看看