Description
子集和问题的一个实例为〈S,t〉。其中,S={ x1 , x2 ,…,xn }是一个正整数的集合,c是一个正整数。子集和问题判定是否存在S的一个子集S1,使得:
。
试设计一个解子集和问题的回溯法。
对于给定的正整数的集合S={ x1 , x2 ,…,xn }和正整数c,计算S 的一个子集S1,使得:
。
Input
输入数据的第1 行有2 个正整数n 和c(n≤10000,c≤10000000),n 表示S 的大小,c是子集和的目标值。接下来的1 行中,有n个正整数,表示集合S中的元素。
Output
将子集和问题的解输出。当问题无解时,输出“No Solution!”。
Samples
Sample #1
Input
5 10
2 2 6 5 4
Output
2 2 6
#include <bits/stdc++.h>
using namespace std;
int sum=0,n,c,a[10001],b[10001],t;
void print(int k){
for(int i=0;i<k;i++){
if(i!=k-1) cout<<b[i]<<" ";
else cout<<b[i]<<endl;
}
}
void f(int m,int sum,int k){
if(t||sum>c){//已找到解或者超过总重
return ;
}
if(sum==c){//等于总重
print(k);
t=1;//找到解
return ;
}
for(int i=m;i<=n;i++){//第m个物品开始进行选择
if(a[i]+sum<=c){//若选择i,不超过总重
b[k]=a[i];//则加入已选择数组
f(i+1,a[i]+sum,k+1);//继续选择下一个物品
}
}
}
int main(){
cin>>n>>c;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=a[i];
}//若大于总重,则输出
if(sum<c) cout<<"No Solution!"<<endl;
else {
f(1,0,0);
if(!t){//若没找到解,则输出
cout<<"No Solution!"<<endl;
}
}
return 0;
}