<aside> 💡 浙江大学算法设计MOOC笔记 + 代码随想录思考
</aside>
<aside>
背景
技巧
</aside>
<aside>
部分
问题,最后综合处理
一次。递归
思想结合规模缩小
,提高算法效率(想想:不断地递归并分治,使得规模不断二分)<aside>
<aside>
替代多重循环,如:n皇后问题。
T function( T f(n) )
<aside>
解决实质是递归形式的问题
递归定义
的,比如不少表达式就是递归定义的:逆波兰,四则运算。逆波兰直接递归
调用自身定义,四则运算则包含项,因子和表达式自身等多个概念,是一种间接递归
调用自身定义“n=1+(n-1)”法
第一步
怎么做,然后再把剩下的问题解决,剩下的问题规模刚好是n-1且解决过程自相似,可以用上递归n-1。e.g.台阶问题“n=(n-1)+1”法
<aside> 💡 附注
atof
函数,将浮点串转变为浮点数cin.peek
函数,提前预知输入而非读取一般可以解决如下几种问题:
- 决策树问题:能否用一颗决策树的step-by-step方式搜索到 Solution?
- 组合问题:N个数里面按一定规则找出k个数的集合
- 切割问题:一个字符串按一定规则有几种切割方式
- 子集问题:一个N个数的集合里有多少符合条件的子集
- 排列问题:N个数按一定规则全排列,有几种排列方式
- 棋盘问题:N皇后,解数独等等
回溯法的解题模板大致如下:路径+递归函数+中间结果
class Solution {
public:
vector<int> path; // 回溯路径
int value; // 中间结果
vector<int> solutions; // 保存结果
// 递归决策函数
void choose(vector<int> &searchSpace, int start) {
// 终止判别
if (done(start)) {
solutions.push_back(value);
return;
}
// 同层决策循环
for (int i = start; i < searchSpace.size(); i++) {
if (!prune(i)) { // 剪枝
// 保存
path.push_back();
update(value);
// 递归
choose(searchSpace, i + 1);
// 回溯
resume(value);
path.pop_back();
}
vector<int> solve(vector<int> &searchSpace) {
int start; // 搜索起始点
initialize(path, value, start);
choose(searchSpace, start);
return solutions;
}
<aside>
<aside>
<aside>
记忆递归型
递归函数+记忆数组
</aside>
<aside>
“人人为我”递推型
1,2,3,...,n-1 => n
递推到“n”时“n”仍未被求出,前面已被求出的状态值用于求“n”的状态值
</aside>
<aside>
</aside>
</aside>