深度优先搜索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 }