从记忆化搜索到动态规划
记忆化搜索
在搜索过程中,如果搜索树中存在大量重复节点,可以通过一个'备忘录'记录第一次搜索到的结果。当下次再遇到该节点时,直接从备忘录中获取结果即可。这里的每一个节点也称为一个状态。
以经典的斐波那契数列为例:
int f[N]; // 备忘录
int fib(int n) {
// 搜索前先查看备忘录
if (f[n] != -1) return f[n];
if (n == 0 || n == 1) return f[n] = n;
// 返回前将结果记录在备忘录中
f[n] = fib(n - 1) + fib(n - 2);
return f[n];
}
递归改递推
在使用记忆化搜索解决斐波那契问题时,观察'备忘录'的填写过程,会发现它是从左往右依次填充的。当位置前面的格子填完后,就可以根据里面的值计算出当前位置的值。因此,整个递归过程也可以改写成循环形式,即递推:
int f[N]; // f[i] 表示第 i 个斐波那契数
int fib(int n) {
// 初始化前两个格子
f[0] = 0; f[1] = 1;
// 按照递推公式计算后面的值
for (int i = 2; i <= n; i++) {
f[i] = f[i - 1] + f[i - 2];
}
return f[n];
}
动态规划基础
动态规划(Dynamic Programming,简称 DP)是一种用于解决多阶段决策问题的算法思想。它通过将复杂问题分解为更小的子问题,并存储子问题的解(通常称为'状态'),从而避免重复计算,提高效率。动态规划本质上蕴含着分治与剪枝的思想。
上述通过记忆化搜索以及递推解决斐波那契数列的方式,其实都属于动态规划的范畴。


