算法简介:将问题分成多个阶段子问题去解决,得到全局最优结果,不是近似结果。
适用条件:1、具有最优子结构
2、无后效性
3、子问题重叠性
三个条件具体体现在下面这个例子:
网上各种资料都有最短路径问题:在初学时为了便于我自己理解该算法的原理,我自己想了这么一个简单暴力的例子。
计算最短路径,只针对这个例子,简单暴力的算法逻辑就是将所有路径遍历一遍。动手试一下!
1)line1:2+3+1+8 = 14
2)line2:2+3+2+4 = 11
3) line3:2+3+3+2 = 10
最后结果显而易见 min = 10。
有想法的同学,就会发现初始的两条路径,会反复计算,2+3 我们一直在重复计算。这就体现了适用条件3,子问题重叠性。
怎么解决这个问题呢,前两条路径重复计算,直接把结果保存下来每次拿来用就好了。现在就变成了:
1)line 1:5+1+8 = 14
2) line 2:5+2+4 = 11
3) line 3:5+3+2 = 10
这个过程就体现了 适用条件2。无后效性,每个状态都是过去历史一个完整总结。
可以认为截至到当前,过去的结果都是最优,这就是适用条件1,最优子结构。
之后的节点值以此类推,将最优结果计算并保存。供下一个节点直接取用。
例如最终值f(n)的计算。一定来自方框的三个节点的最优值f(n-1,i)加上最后的路径的值x(n-1,i)。
牵出来状态转移方程 f(n) = min{f(n-1,i)+x(n-1,i)} 这个是代码设计核心。
-------------------------------------以上纯属个人理解,欢迎大牛批评指出-------------------------
动态规划的好处:1)以空间换时间,仔细想想例子,过程中我们需要记录每个阶段产生的最优结果。但是避免了重复计算子问题。利用动态规划,例子中的 加法次数有所减少。
2)代码易于设计,优秀的算法设计方案带来的效果