一、对回溯算法的理解
根据给定的要求进行递归的计算。
每一次的递归,符合给出的特定条件时,暂时保存当前的状态,进入下一层的计算;否则,退出当层的计算,并根据是否有返回值来决定是否更新上一层的状态。
也就是说,回溯算法一定要给出限界函数,不然会一直递归下去,最后爆栈。
二、“子集和”问题的解空间结构和约束函数
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; }
三、在本章学习过程中遇到的问题及结对编程的情况
回溯算法有时候的约束函数会写错,有时候剪枝也会剪错。