演算法第5章作業
阿新 • • 發佈:2018-12-18
一、對回溯演算法的理解
根據給定的要求進行遞迴的計算。
每一次的遞迴,符合給出的特定條件時,暫時儲存當前的狀態,進入下一層的計算;否則,退出當層的計算,並根據是否有返回值來決定是否更新上一層的狀態。
也就是說,回溯演算法一定要給出限界函式,不然會一直遞迴下去,最後爆棧。
二、“子集和”問題的解空間結構和約束函式
1、解空間
二維陣列
2、約束函式
if(s > k){ --t; return ; }
假如上一層的選擇的和與當前層的數相加大於目標,就不選擇。
3、程式碼
#include <iostream> using namespace std; int n, k; int sum = 0, t = 0; bool is = false; int num[10005], ans[10005]; void dfs(int s, int x){ s += num[x]; ans[t++] = num[x]; if(s == k){ is = true; return ; } else if(s > k){--t; return ; } else { for(int i = x+1; i <= n; ++i){ dfs(s, i); if(is){ return ; } } } --t; return ; } int main(){ scanf("%d %d", &n, &k); for(int i = 1; i <= n; ++i){ scanf("%d", &num[i]); sum += num[i]; } if(sum < k){ printf("No Solution!"); } else{ for(int i = 1; i <= n; ++i){ dfs(0, i); if(is){ for(int j = 0; j < t; ++j){ printf("%d ", ans[j]); } break; } } if(!is){ printf("No Solution!"); } } return 0; }
三、在本章學習過程中遇到的問題及結對程式設計的情況
回溯演算法有時候的約束函式會寫錯,有時候剪枝也會剪錯。