记忆化搜索
求 Fibonacci 第 $i$ 项的深搜程序如下:
int f(int x) {
if (x <= 2) return 1;
return f(x - 1) + f(x - 2);
}
该程序直观,但运行效率低. 以 $f(7)$ 为例,列出函数调用情况:
随着 $n$ 的增大,$f(n)$ 的时间复杂度呈指数级增长. 我们发现,有很多函数被重复调用. 使用「记忆化搜索」可避免此情况.
建立数组 $F$ 保存计算结果.
- 若 $f(x)$ 未被调用过,算出 $f(x)$ 的值,并存入 $F[ x]$
- 若 $f(x)$ 已被调用过,直接返回 $F[ x]$
int F[];
F[1] = F[2] = 1;
int f(int x) {
if (F[x] != 0) // 若 F[x] 有值,则说明 f(x) 被调用过
return F[x];
return F[x] = f(x - 1) + f(x - 2); // 返回时保存
}
记忆化搜索的时间复杂度与动态规划相当,但效率略低. 若动态规划难以设计,则可以采用该算法.