果园里有位花匠,每年要在一片桃林里找出产量最高的那一枝。他的老办法是:从树根开始,每一根枝条都顺着摸下去,一直摸到最细的末梢,把所有可能的「枝路」都走一遍。
这片林子每根枝条都会分成两根,一共分 30 层。算了一下,末梢的数量是 230 —— 超过十亿。花匠摸一辈子也摸不完。
后来他学了三招:
第一招:看到某根枝条已经枯了,或者明显长不出果子,直接咔嚓剪掉,不再往下摸。反正往下摸也不会有好结果。
第二招:他手里已经记着「目前最高的产量是 100 斤」。走到某个分叉时,抬头一看 —— 这根枝上所有的果子加起来也只有 60 斤,就算全给它也不如手里的 100 斤。于是整根剪掉。
第三招:摸到某根枝条时,他发现这根枝条和上个月摸过的那根长得一模一样,位置、朝向、粗细全一样。他翻开随身带的小本子:「这根的答案上次已经算过了,是 78 斤。」直接抄,不用再摸。
「剪掉一根枝,省下的不是一根枝,而是它下面整棵树。」
这三招,就是信息学里的 剪枝(pruning) 与 记忆化(memoization)。它们让原本「指数爆炸、永远算不完」的搜索,在有限时间内给出答案。
💡 搜索的本质:枚举 + 提前否决
搜索(DFS / BFS / 回溯)说到底就是把所有可能的情况枚举一遍。只要问题规模稍微大一点,枚举量就会以指数速度增长。
但请注意:绝大多数分支从一开始就不可能通向答案。剪枝做的事情,就是「在还没走到尽头之前,就判断出这条路走不通」,然后整块跳过 —— 跳过的是一整棵子树,而不是一个节点。
而记忆化解决的是另一个问题:不同的路径常常会走到同一个状态,同一个状态的最优解只需要算一次。把答案记下来,下次直接查表。
一句话总结:剪枝砍「不可能」的分支,记忆化省「重复」的计算。