一、对回溯算法的理解
我认为回溯算法其实是一种近似于“试探”的过程,它根据一个树形的结构,进行一层层的试探,最终得到想要的结果。在每一次的递归中,当出现符合条件的答案时,便保存当前的状态,进入下一层的计算;否则,返回上一层,进行下一步的计算。所以在回溯算法中必须给出限界函数,否则递归便不会终止。
二、“子集和”问题:解空间结构和约束函数
解空间:被选择的、用于相加的数字组合。
约束函数:当当前选择的数字之和大于所要求的和值,则返回上一层。
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 }
三、在本章学习过程中遇到的问题及结对编程情况
在编写回溯的过程中,有时对于何时进入下一层的判断不够清晰,用于剪枝的方式可能会出现没有考虑到的问题,从而导致各种各样的错误。在和同伴结对编程的过程中,我们一起讨论各种剪枝、限界的方法,也对递归有了更进一步的认识。