一.动态规划三要素
- 最优子结构
- 全局最优解一定包含子问题的最优解。
- 递推公式(状态转移方程)
- 比较大的问题一定可以通过它前面的比较小的一个或几个问题推导出来。比如在打家劫舍的问题中,3号位置的解取决于1号和2号位置的解。(3号位置的解可以由1号和2号位置的最优解推导出来)。偷前三家能偷到的最大金额f(3),等于什么呢。就两种可能,要么,①我偷第三家,那么我不能偷第二家,即现在能偷到的最大金额为,f(1)-偷前一家的最优解 + 偷第三家的金额数。(由于小偷不能偷连续的两家,所以在①这种情况中,打算偷第三家,就不能偷第二家。)用公式表示就是,f(3) = f(1) + nums[3]. 再看第二种情况,② 我不偷第三家。这意味着我可以偷第二家。如果第二家是个大富翁,那我就赚大啦!所以我可能放弃偷第三家。而选择偷第二家。这种情况的偷前三家的最优解f(3)就是,偷前两家的最优解f(2)。公式表示就是,f(3)=f(2)。现在我们从①和②中取一个大的,就是我今晚的行动方案,即f(3) = max(f(1)+nums[3],f(2));这个就是状态转移方程。
- 重叠子问题
- 大问题是由小问题组成的。
二.来源
在用递归解决重叠子问题的时候,会发现有很多问题的解被重复计算。浪费了大量的时间。于是我们想到,能不能用一个数组来把算过的值保存下来,下次要用的时候,直接从这个数组里取值不就行啦。于是dp[]产生了。
用迭代取代递归。众所周知递归代码写起来简单,运行起来效率低。迭代取代递归可以大幅度的提升效率。