1. 程式人生 > >演算法第五章作業

演算法第五章作業

一、對回溯演算法的理解

       我認為回溯演算法其實是一種近似於“試探”的過程,它根據一個樹形的結構,進行一層層的試探,最終得到想要的結果。在每一次的遞迴中,當出現符合條件的答案時,便儲存當前的狀態,進入下一層的計算;否則,返回上一層,進行下一步的計算。所以在回溯演算法中必須給出限界函式,否則遞迴便不會終止。

二、“子集和”問題:解空間結構和約束函式

       解空間:被選擇的、用於相加的數字組合。

       約束函式:噹噹前選擇的數字之和大於所要求的和值,則返回上一層。

       

 1 #include <iostream>
 2 using namespace std;
 3 int a[10005],ans[10005],cnt=0;
 4 int n,k,flag=0,ok=0;
 5 
 6 void dfs(int i,int sum){
 7     if(i==n+1&&sum!=k){
 8         return;
 9     }
10     if(sum==k){
11         flag=1;
12         if(!ok){
13             for
(int i=0;i<cnt;i++){ 14 cout<<ans[i]<<" "; 15 } 16 ok=1; 17 } 18 return; 19 } 20 if(!ok&&sum+a[i]<=k){ 21 sum+=a[i]; 22 ans[cnt++]=a[i]; 23 dfs(i+1,sum); 24 sum-=a[i]; 25 ans[--cnt]=0
; 26 } 27 dfs(i+1,sum); 28 } 29 30 int main(){ 31 int t; 32 cin>>n>>k; 33 for(int i=1;i<=n;i++){ 34 cin>>a[i]; 35 t+=a[i]; 36 } 37 if(t<k){ 38 cout<<"No Solution!"<<endl; 39 return 0; 40 } 41 dfs(1,0); 42 if(!flag){ 43 cout<<"No Solution!"<<endl; 44 } 45 }

三、在本章學習過程中遇到的問題及結對程式設計情況

       在編寫回溯的過程中,有時對於何時進入下一層的判斷不夠清晰,用於剪枝的方式可能會出現沒有考慮到的問題,從而導致各種各樣的錯誤。在和同伴結對程式設計的過程中,我們一起討論各種剪枝、限界的方法,也對遞迴有了更進一步的認識。