比赛描述
子集和问题的一个实例为〈S,t〉。其中,S={ 1 x , 2 x ,…, n x }是一个正整数的集合,c是一个正整数。子集和问题判定是否存在S的一个子集S1,使得 ,试设计一个解子集和问题的回溯法。
对于给定的正整数的集合S={ x 1, x 2,…,x n }和正整数c,编程计算S 的一个子集S1,使得。
输入
由文件input.txt 提供输入数据。文件第1 行有2 个正整数n 和c,n 表示S 的大小,c是子集和的目标值。接下来的1 行中,有n 个正整数,表示集合S 中的元素。
输出
输出共有10行,在第k行输出页码中用到数字k-1 的次数,k=1,2,…,10。
样例输入
5 10
2 2 6 5 4
样例输出
2 2 6
提示
undefined
题目来源
算法设计与实验题解
/* // TL3 #include<iostream> #define MAX_N 1001 int n,c,a[MAX_N]; bool selected[MAX_N]; bool makeSum(int i, int sum){ if(sum==0){ return 1; } if(sum<0 || i>=n){ return 0; } selected[i] = 1; if(makeSum(i+1,sum-a[i])){ return 1; } selected[i] = 0; if(makeSum(i+1,sum)){ return 1; } return 0; } int main(){ int i; scanf("%d%d",&n,&c); for(i=0;i<n;i++){ scanf("%d",a+i); } if(makeSum(0,c)){ for(i=0;i<n;i++){ if(selected[i]){ printf("%d ",a[i]); } } printf("\n"); }else{ printf("No Solution!"); } } */ /* Wrong Answer at Test 11 #include<iostream> #define MAX_N 1001 int n,c,a[MAX_N],s[MAX_N]; bool selected[MAX_N]; bool makeSum(int i, int sum){ if(sum==0){ return 1; } if(sum<0 || i>=n || (i<n-1 && sum>s[i+1])){ return 0; } selected[i] = 1; if(makeSum(i+1,sum-a[i])){ return 1; } selected[i] = 0; if(makeSum(i+1,sum)){ return 1; } return 0; } int main(){ int i; scanf("%d%d",&n,&c); for(i=0;i<n;i++){ scanf("%d",a+i); } s[n-1]=a[n-1]; for(i=n-2;i>=0;i--){ s[i] = s[i+1]+a[i]; } if(makeSum(0,c)){ for(i=0;i<n;i++){ if(selected[i]){ printf("%d ",a[i]); } } printf("\n"); }else{ printf("No Solution!"); } } */ #include<iostream> #define MAX_N 2001 int n,c,a[MAX_N],s[MAX_N]; bool selected[MAX_N]; bool makeSum(int i, int sum){ if(sum==0){ return 1; } if(sum<0 || i>=n || (i<n-1 && sum>s[i+1])){ //剪枝很重要 return 0; } selected[i] = 1; if(makeSum(i+1,sum-a[i])){ return 1; } selected[i] = 0; if(makeSum(i+1,sum)){ return 1; } return 0; } int main(){ int i; scanf("%d%d",&n,&c); for(i=0;i<n;i++){ scanf("%d",a+i); } s[n-1]=a[n-1]; for(i=n-2;i>=0;i--){ s[i] = s[i+1]+a[i]; } if(makeSum(0,c)){ for(i=0;i<n;i++){ if(selected[i]){ printf("%d ",a[i]); } } printf("\n"); }else{ printf("No Solution!"); } }