已知n(0<n<=20)个不同正整数wi,0<=i<=n-1,的集合,求该集合的所有满足条件的子集,使得每个子集中的正整数之和等于另一个给定的正整数M。
【输入】
第一行输入n和M的值,第二行输入n个不同的正整数wi(i=0,…,n)。
【输出】
如果有答案,则输出所有满足条件的子集(用固定长度n-元组xi表示,xi=0或1,i=0,…,n)。如果没有答案,则输出“no solution!”。
【输入样例】
4 31
11 13 24 7
【输出样例】
1 1 0 1
0 0 1 1
#include<iostream>
#include<algorithm>
using namespace std;
int count=0;
void SumOfSub(float s,int k,float r,int *x,float m,int *w,int n,int *t) {
x[k]=1;
if(s+w[k]==m) {
int *tmp=new int[n];
for(int i=0;i<n;i++){
for(int j=0; j<n; j++) {
if(w[i]==t[j]&&x[i]==1){
tmp[j]=1;
}
if(w[i]==t[j]&&x[i]!=1){
tmp[j]=0;
}
}
}
for(int i=0;i<n;i++)
cout<<tmp[i]<<" ";
cout<<endl;
}
else if(s+w[k]+w[k+1]<=m){
SumOfSub(s+w[k],k+1,r-w[k],x,m,w,n,t);
}
if((s+r-w[k]>=m)&&(s+w[k+1]<=m)){
x[k]=0;
SumOfSub(s,k+1,r-w[k],x,m,w,n,t);
}
}
int main() {
int n,m;
cin>>n>>m;
int *w=new int[n];
int *t=new int[n];
for(int i=0;i<n;i++){
cin>>w[i];
t[i]=w[i];
}
int *x=new int[n];
float r=0;
for(int i=0;i<n;i++){
r=r+w[i];
x[i]=0;
}
sort(w,w+n);
if(r>=m&&w[0]<=m)
SumOfSub(0,0,r,x,m,w,n,t);
return 0;
}