动态规划在算法中的应用

DP(Dynamic programming)动态规划是一种在算法中经常使用到的思想,大多时候都使用在寻找最优解的算法中。对于DP,注意它不是一种算法而是一种思想一种算法。
在介绍DP之前,介绍其他几种思想,首先是贪心
贪心是讲在当前选择中要挑选一种最优的,这样累加到最后,结果就是最优的。在大多数情况下,寻找最优解中贪心算法的效率会稍微优于DP;但是当数据量大到一定程度之后DP就体现出了它的优势。因为对于贪心算法,它每次都计算得出当前选择的最优解。
除了效率上的差别之外,贪心算法在某些时候可能并不是最优的。这就表示贪心算法有时候需要证明其结果的正确性。有的时候结果不正确的主要原因还是贪心的算法本质。贪心每次选择都是最优的,因为有的问题不仅仅是要考虑一个方面,还需要结合其他限制条件。最经典的就是背包问题。
然后介绍的是递归。递归在需要计算同样问题的时候经常被用到,最经典的就是斐波那契数列。因为每次计算序列都是相同的方法,使用递归很方便。但是起最大的问题就是重复计算。当计算某个值K的时候,前面的数值(1-K)要重复计算很多遍。当值K比较大的时候,这个重复计算量相应的也增大到不可忽略。
在我们常见的开发过程中,DP、贪心和递归是经常被对比到的,在某些时候使用哪种办法需要看不同场景,这个就和各种排序算法一样,多种办法能达到目的,就选择一种比较适合场景的。

下面就开始介绍DP到底是个什么东西。
通过查看DP维基发现其在重叠子问题和寻找最优解的时候被经常用到。从这可以看出它的使用场景就是待解决问题可以分解成很多重复的子问题。这又是我们为何举出贪心和递归俩个例子的原因。
所以在遇到一个问题能否使用到DP,那就先看是否对该问题进行分解成一个个的子问题。下面直接上例子,首先最经典的背包问题:
1:给定体积为w的背包,和一个二维k*2的数组a[k][2],有其中a[i][0]=wi,a[i][1]=vi,即第i个数组表示体积为wi的价值为vi,问背包能最多装多大价值的东西?
首先通过贪心去解决的话,那么每次都选择价值最大的,这样最后的价值也最大?可以看出上面一句是用了问号,结果不是这么简单。因为题目有俩个参考纬度,一个是价值,还有两位一个是体积。俩者结合才能得到最优解。
那么我们试着使用动态规划去解决。上面已经见过DP在可以分解子问题的算法中使用,那首先需要分解子问题。
先加上DP[i]=Vi,当背包装取了体积为i的时候价值为Vi,它的子问题是什么。DP[i]肯定是加了一个体积为Wj之后,才到达体积Vi的。所以
DP[i] = DP[i - Wj] + Vj

在举下个例子之前先对上面问题再进行一定的抽象。
DP要求分解子问题,不过一般被称为状态。对于背包来说
DP[1]:V1就是一个状态,即当装了体积为1的时候,背包的价值为V1;
DP[2]:V2是另外一个状态,即当装了体积为2的时候,背包的价值为V2;
V1->V2肯定有关系的,当中对于背包已经有1的时候再添加体积1,状态才由V1变到了V2.
因此使用DP的方法可以概括为俩点,寻找状态V和V1->V2的状态转移方程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值