• 部分和问题(dfs)


    部分和问题

    描述

    给定整数a1a2.......an,判断是否可以从中选出若干数,使它们的和恰好为K

    输入

    首先,nkn表示数的个数,k表示数的和。
    接着一行n个数。
    1<=n<=20,保证不超int范围)

    输出

    如果和恰好可以为k,输出“YES”,并按输入顺序依次输出是由哪几个数的和组成,否则“NO”

    样例输入

    4 13

    1 2 4 7

    样例输出

    YES

    2 4 7

     1  //不保存符合条件的每一个数
     2   #include<iostream>
     3   int a[25];
     4   int n,k;//全局变量
     5   using namespace std;
     6   bool dfs(int i,int sum){//已经从前i项得到了和sum,然后从i项之后进行深度搜索 
     7      if(i==n+1)
     8           return sum==k; //如果前n项都计算过了,则返回并判断sum是否与K相等 
     9       if(dfs(i+1,sum))//不加a[i]的情况 
    10          return true;
    11      if(dfs(i+1,sum+a[i]))//加上a[i]的情况 
    12          return true;
    13      return false;  //无论加上a[i]还是不加上a[i]都不能使得sum==k,则返回flase 
    14  }
    15  int main(){
    16      cin>>n>>k;
    17      for(int i=1;i<=n;i++)
    18          cin>>a[i];
    19      if(dfs(1,0))//从1开始,因为题目中1<=n<=20 
    20          cout<<"YES"<<endl;
    21      else
    22          cout<<"NO"<<endl;
    23      return 0;
    24  }
    25 //深度优先搜索从最开始的状态出发,遍历所有可以达到的状态,由此可以对所有的状态进行操作,或列举出所有的状态

    保存并输出符合条件的数据:

     1 #include<iostream>
     2 int a[25],b[25]={0};//b[25]初始化零,用于标记符合条件的数据 
     3 int n,k;
     4 using namespace std;
     5 int dfs(int i,int sum)
     6 {
     7     if(i==n+1&&sum==k)
     8         return 1;
     9     if(i==n+1&&sum!=k)
    10         return 0;
    11     b[i]=0;//标记为0,数据不符合 
    12     if(dfs(i+1,sum))
    13         return 1;
    14     b[i]=1;//标记为1,数据符合 
    15     if(dfs(i+1,sum+a[i]))
    16         return 1;
    17     return 0;
    18 }
    19 int main()
    20 {
    21     while(cin>>n>>k){
    22         int p=0;
    23     for(int i=1; i<=n; i++)
    24         cin>>a[i];
    25     if(dfs(0,0)){
    26         cout<<"YES"<<endl;
    27         for(int i=1; i<=n; i++){
    28             if(b[i])
    29                 cout<<a[i]<<" ";
    30         }
    31         cout<<endl;
    32     }
    33     else
    34         cout<<"NO"<<endl;
    35     }
    36     
    37     return 0;
    38 }

    测试结果:

  • 相关阅读:
    Git标签使用技巧
    Git入门基本概述
    过滤器+缓存在.NET5WebApi项目中的简单使用
    在.NET5中 使用JWT鉴权授权
    Git常用开发命令
    时间戳的实际使用
    两个日期字段相减,进行计算
    MQ的理论理解
    第一周学习C语言的总结!
    问题(the question)
  • 原文地址:https://www.cnblogs.com/geziyu/p/9278465.html
Copyright © 2020-2023  润新知