子集和問題


子集和問題

Time Limit: 1000 ms Memory Limit: 65536 KiB
子集和問題的一個實例為〈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!”。

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 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM