动态规划与搜索递推的区别

动态规划是解决某一类的问题,而不在于纠结递推还是递归,内存换时间。

CPU内存里存储的所有数据构成了当前状态,CPU只能利用当前状态计算出下一个状态。

下一个状态只能由当前状态计算出来。

斐波那契,每求一个新数只需要之前的两个状态,只需要依照固定的模式从旧状态计算出新状态就行。
不需要考虑是不是需要更多的状态,也不需要选择哪些旧状态来计算新状态。对于这样的解法,叫做递推。

斐波那契例子过于简单,让人忽略了阶段的概念。阶段是指在同一时刻可能会得到的不同状态的集合。斐波那契中每一步计算得到一个新数字,所以每一个阶段只有一个状态,加入把你放在围棋棋盘上,每一步只能走一格,每一步都有东南西北四个方向可以走,所以当你同样走四步可能会处于很多个不同的位置,从头开始走了几步就是第几个阶段,走了n步可能处于的位置称为一个状态,走了这n步所有可能到达的位置的集合就是这个阶段下所有可能的状态。

每个阶段有很多个状态

好在有时我们并不需要真的计算所有状态,比如:从棋盘上的左上角到右下角最短需要几步。
每个阶段确实可以有很多状态(走n步可以走很多位置),但是同样的n步中,有哪些位置可以让我们在n+1步中走的最远呢?没错,正是第n步中走的最远的位置(?)。下一步最优是从当前最优得到的,所以为了计算最终的最优值,只需要存储每一步的最优值即可,解决这种性质的问题的算法叫贪心,如果只看最优状态之间的计算郭晨是不是很像,所以计算的方法是递推。

问题划分为阶段和状态。这样一来我们一下子就解决了大类问题,一个阶段的最优可以由前一个阶段的最优得到

如果一个阶段的最优无法用前一个阶段的最优得到呢?

什么你说只需要之前两个阶段就可以得到当前最优?那跟只用之前一个阶段并没有本质区别。最麻烦的情况在于你需要之前所有的情况才行。

再举迷宫的例子,在计算从起点到终点的最短路线时,你不能只保存当前阶段的状态,因为题目要求最短,所以你必须知道之前走过的所有位置。因为即使你当前在的位置不变,之前的路线不同会影响你的之后走的状态。这时你需要保存的是之前每个阶段所经历的那个状态,根据这些信息才能计算出下一个状态。

每个撞他都可以转移到下一个阶段的多个状态,解的复杂度就是指数的,之前的路线会影响到下一步的选择,这个叫做后效性。

刚刚的情况实在太普遍,解决方法实在太暴力,有没有哪些情况可以避免如此的暴力呢?

契机就在于后效性。

有一类问题,看似需要之前所有的状态,其实不用。不妨也是拿最长上升子序列的例子来说明为什么他不必需要暴力搜索,进而引出动态规划的思路。

最长的上升子序列问题:

输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。

从头到尾依次枚举是否选择当前的数字,每选定一个数字就要去看看是不是满足“上升”性质,这里的第i个阶段就是去思考是否选择第i个数,第i个阶段有两个状态,分别是选和不选。(迷宫是东南西北)。而这里因为是需要上升的序列,每次我选择当前数字的时候,只需要和之前选定的数字比较就行了!这和之前的迷宫问题有本质不同、这就可以纵容我们不需要记录之前所有的状态啊!既然我们的选择已经不受之前状态的组合的影响了,那时间复杂度自然也不是指数的了啊!虽然我们不在乎某序列之前都是什么元素,但我们还是需要这个序列的长度的。所以我们只需要记录以某个元素结尾的LIS长度就好!因此第i个阶段的最优解只是由前i-1个阶段的最优解得到的,然后就得到了DP方程
在这里插入图片描述
所以一个问题是该用递推、贪心、搜索还是动态规划,完全是由这个问题本身阶段间状态的转移方式决定的!
每个阶段只有一个状态->递推;
每个阶段的最优状态都是由上一个阶段的最优状态得到的->贪心;
每个阶段的最优状态是由之前所有阶段的状态的组合得到的->搜索;
每个阶段的最优状态可以从之前某个阶段的某个或某些状态直接得到而不管之前这个状态是如何得到的->动态规划。

每个阶段的最优状态可以从之前某个阶段的某个或某些状态直接得到这个性质叫做最优子结构;

而不管之前这个状态是如何得到的这个性质叫做无后效性。

另:其实动态规划中的最优状态的说法容易产生误导,以为只需要计算最优状态就好,LIS问题确实如此,转移时只用到了每个阶段“选”的状态。但实际上有的问题往往需要对每个阶段的所有状态都算出一个最优值,然后根据这些最优值再来找最优状态。比如背包问题就需要对前i个包(阶段)容量为j时(状态)计算出最大价值。然后在最后一个阶段中的所有状态种找到最优值。

作者:王勐
链接:https://www.zhihu.com/question/23995189/answer/35429905
来源:知乎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值