题目:
设集合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
分析:
#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
请按任意键继续. . .