子集和問題
Time Limit: 1000 ms Memory Limit: 65536 KiB
子集和問題的一個實例為〈S,t〉。其中,S={ x1 , x2 ,…,xn }是一個正整數的集合,c是一個正整數。子集和問題判定是否存在S的一個子集S1,使得:
。
試設計一個解子集和問題的回溯法。
對於給定的正整數的集合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!”。
Sample Input
5 10 2 2 6 5 4
Sample Output
2 2 6
Hint
Source
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n,c; 4 int data[10001]; 5 int ans[10001]; 6 bool flag=false; 7 int sum,k; 8 void dfs(int i){ 9 if(flag) return ;//找到了一個 就可以直接返回了 10 sum+=data[i];//還未找到,繼續 加 11 ans[k++]=data[i];//存上 這個 數據 12 if(sum>c) return ;//sum 超過要找的c 剪枝 13 if(sum==c) { flag=true; return ;}//找到結果,返回 14 for(int j=i+1;j<=n;j++){// 直接傳(i+1) 不對 15 dfs(j);//繼續遍歷下面的數據 16 if(!flag){//sum!=c 的時候 ,不滿足,回溯,恢復數據 17 sum-=data[j];//總和減去 這個數據 這里容易寫錯 是j不是 i 18 k--;//存答案的數據 要 減去 這個不滿足的數據 19 } 20 } 21 } 22 int main() 23 { 24 cin>>n>>c; 25 int tmpSum=0;//如果 不寫這個 與判斷的 ,可能 這個數據很大,浪費時間 超時 26 sum=0,k=0; 27 for(int i=0;i<n;i++){ 28 cin>>data[i]; 29 tmpSum+=data[i]; 30 } 31 if(tmpSum<c){// 預判 全部的 數據和 是否能達到 要求的c 32 cout<<"No Solution!"<<endl; 33 return 0; 34 } 35 dfs(0);//開始搜索 36 if(flag){//找到一個 結果 37 for(int i=0;i<k;i++){//遍歷輸出 38 cout<<ans[i]; 39 if(i!=k-1) 40 cout<<" "; 41 } 42 cout<<endl;//加不加都對 43 }else cout<<"No Solution!"<<endl; 44 return 0; 45 }