前言
动态规划在基础算法中具有比较重要的地位,来看看它。
正文
什么是动态规划(Dynamic Programming)?
刚入门的时候特别不容易理解。这里在知乎的问答中找到了一篇很容易入门的介绍,感谢这位大神
https://www.zhihu.com/question/23995189/answer/613096905
对其做一些总结行归纳:
1.基本内涵
能将大问题拆成几个小问题,且满足无后效性、最优子结构性质。
ps:文中举了个栗子,1、5、11面额凑出15,如何使用最小的张数凑出?
最佳答案 15 = 5+5+5 3张凑出
1)大问题拆小问题
首先分析问题,找到规律。
令cost代表张数,拼凑方式将有下面三种:
当选了 1 张11 , cost(15) = 1 + cost(15-11)
当选了 1 张5 , cost(15) = 1 + cost(15-5)
当选了 1 张1 , cost(15) = 1 + cost(15-1)
!!不会再有其他情况
cost(n) 只与 cost(n-11) , cost(n-5) , cost(n-1) 相关;更确切地说:
cost(n) = min{cost(n-11) , cost(n-5) , cost(n-1)} + 1
2)无后效性
cost(15)仅与cost(15-11), cost(15-5) ,cost(15-1)相关,至于这三个数怎么求出来,与它无关。求出cost(15)后,后面任意时刻直接使用它的值即可,不用管怎么求出来的。 如果给定某一阶段的状态,则在这一阶段以后过程的发展不受这阶段以前各段状态的影响,这就是无后效性
3)最优子结构
cost(n) = min{cost(n-11) , cost(n-5) , cost(n-1)} + 1 这里形成了转移公式,其中的min很显然是取cost(n-11) , cost(n-5) , cost(n-1)中最小的组合,意味着cost(n)本身就是最优结构。它的子问题也是最优子结构。
2.核心竞争力
对于相关问题很明显也可以用暴力解法,为什么要使用DP呢?
因为快,以上面的例子做参考,当cost(n) 聚焦到
min{cost(n-11), cost(n-5) , cost(n-1)}时,它就形成了最优空间。15张1这样的情况,它根本不会去计算。仅枚举有希望成为答案的解,自带剪枝功能。
3.如何应用DP
1)状态设计
以上面的例子做参考,
设计了cost(n),它代表了组合结果为n的最小张数。
2)状态转移方程
这里🈯️从小问题如何推到大问题
cost(n) = min{cost(n-11) , cost(n-5) , cost(n-1)} + 1
3)缓存小问题答案
当我们求cost(15)时,我们需要求cost(15-11)也就是cost(4), 同理还有cost(10) , cost(14)。这些小问题的解其实是唯一的,这时候把它缓存下来,可以提升效率。
例如,我们求了cost(15)后缓存下来,它可以作为cost(20)的一个子问题的解,不用再算一遍。