深度优先搜索DFS---序列求和问题(1)

题目:

  给定N 个整数(可能有负数),从中选择 K个数,使得这 K个数之和恰好等于一个给定的整数 X;如果有多种方案,那么选择它们中元素平方和最大的一个。例如,从4个整数{ 2, 3, 3 ,4}中选择 2个数(集合中的每一个数只能被选一次),使它们的和为 6。显然有两种方案{2,4}和{3, 3},其中平方和最大的方案为{2, 4}。数据保证存在唯一。

输入格式:

第一行给出 一个正整数 N( 1<=N<=20)

第二行给出N个整数(可能有正有负,可能不按数的大小顺序给出),中间以空格隔开。

第三行给出选择元素 K个数 ,以及它们的和 X

输出格式:

按递增的方式输出序列。

输入样例:

4   //4个元素

2 3 3 4 //4个元素的值

2 6 //选择 2个元素,之和为 6

输出样例

2 4

直接给出代码。

自我规定:当有多个递归边界时,通常把”判断是否是答案“的条件作为递归边界一

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 const int maxn = 30;
 7 int A[maxn] = {0};
 8 int n,k,x,maxSumSqu= -1;
 9 vector<int> temp,ans;
10 void DFS(int index, int nowK,int sum,int sumSqu) {
11     if(nowK == k && sum == x) {//递归边界一
12         if(maxSumSqu < sumSqu) {
13             maxSumSqu = sumSqu;
14             ans = temp; //vector之间等号赋值,仅限 Int
15         }
16         return ;
17     }
18     if(index == n || nowK > k || sum > x) return ;//递归边界二
19     temp.push_back(A[index]);
20     DFS(index+1,nowK+1,sum+A[index],sumSqu+A[index]*A[index]);    //"选择"index号数
21     temp.pop_back();
22     DFS(index+1,nowK,sum,sumSqu);//"不选择"index号数
23 }
24 
25 int main() {
26     cin>>n;
27     for(int i = 0; i < n; ++i)
28         cin>>A[i];
29     cin>>k>>x;
30     DFS(0,0,0,0);//初始参数一般都为 0
31     sort(ans.begin(),ans.end());
32     for(int i = 0; i < ans.size(); ++i) {
33         if(i > 0) printf(" ");
34         printf("%d",ans[i]);
35     }
36     return 0;
37 }

运行结果:

题目修改:

假设 N个整数中的每一个都可以被选择多次,那么选择 K个数,使得 K个数之和恰好为X。

只需修改一处代码即可,那么可以持续选择index号数,直至不再选择index号数,再转入“不选index号数”的分支。

 1 #include<iostream>
 2 #include<vector>
 3 #include<algorithm>
 4 using namespace std;
 5 
 6 const int maxn = 30;
 7 int Set[maxn] = {0};
 8 int n,x,sum,MAXSqu= -1;
 9 vector<int> temp,ans;
10 void DFS(int index, int nowX,int nowSum,int nowSqu) {
11     if(nowX == x && nowSum == sum) {//递归边界一 
12         if(MAXSqu < nowSqu) {
13             MAXSqu = nowSqu;
14             ans = temp; //vector之间等号赋值,仅限 Int
15         }
16         return ;
17     }
18     if(index == n || nowX > x || nowX > sum) return ;//递归边界二 
19 
21     temp.push_back(Set[index]);//保存当前元素
22     DFS(index, nowX+1,nowSum + Set[index],nowSqu +Set[index]*Set[index]);//“选择”当前 index号数 
23     temp.pop_back();
25     DFS(index + 1,nowX,nowSum,nowSqu); //“不选择”当前 index 号数
26 }
27 
28 int main() {
29     cin>>n;
30     for(int i = 0; i < n; ++i)
31         cin>>Set[i];
32     cin>>x>>sum;
33     DFS(0,0,0,0);
34     sort(ans.begin(),ans.end());
35     for(int i = 0; i < ans.size(); ++i) {
36         if(i > 0) printf(" ");
37         printf("%d",ans[i]);
38     }
39     return 0;
40 }

 

posted @ 2020-02-27 10:25  tangq123  阅读(587)  评论(0编辑  收藏  举报