回溯法解子集和问题

Isoke ·
更新时间:2024-11-11
· 896 次阅读

题目:
设集合S={x1,x2,…,xn}是一个正整数集合,c是一个正整数,子集和问题判定是否存在S的一个子集S1,使S1中的元素之和为c。试设计一个解子集和问题的回溯法。

输入格式:

输入数据第1行有2个正整数n和c,n表示S的大小,c是子集和的目标值。接下来的1行中,有n个正整数,表示集合S中的元素。
是子集和的目标值。接下来的1 行中,有n个正整数,表示集合S中的元素。

输出格式:

输出子集和问题的解,以空格分隔,最后一个输出的后面有空格。当问题无解时,输出“No Solution!”。

输入样例:

在这里给出一组输入。例如:

5 10
2 2 6 5 4

输出样例:

在这里给出相应的输出。例如:

2 2 6

分析:

题意是在数组的序列中找到第一组的和为c的子集和,如果没找到就输出No Solution! 用一个后缀和数组:例如:a={1,2,3}, 则b={6,5,3} c++代码如下: #include using namespace std; #define M 10001 int n, c, sum=0,k=0;//sum解的个数 int a[M], b[M];//k所选数字的和 int used[M]; void dfs(int t){ //试探第t个数是否能取 if(sum>0){ //一旦找到解就直接退出 return; } if(k+b[t] <c){//如果t~n的数的和都比 c还小,退出剪枝 return; } if(k == c){ for(int i=1;i<=n;i++){ if(used[i] ) cout<<a[i]<n) return;//边界 if(k+a[t] > c){//加上a[t]如果>c,不考虑它 dfs(t+1); return;//不进行下面 } k+=a[t]; //用a[t] used[t]= 1; dfs(t+1); k-=a[t]; //不用a[t] used[t] = 0; dfs(t+1); return; } main() { int i; cin>>n>>c; memset(used,0,sizeof(used)) ; for( i=1;i>a[i]; } for(i=n-1,b[n]=a[n]; i>=1;i--){// **后缀和** b[i]=a[i]+b[i+1]; } dfs(1); if(sum == 0){ cout<<"No Solution!"; } return 0; }

运行结果:

5 3
2 2 6 5 4
No Solution!

Process exited after 28.69 seconds with return value 0
请按任意键继续. . .

北斋~~书生 原创文章 48获赞 9访问量 1万+ 关注 私信 展开阅读全文
作者:北斋~~书生



子集 回溯法

需要 登录 后方可回复, 如果你还没有账号请 注册新账号