动态规划(Dynamic Programming)

Dynamic programming is a method for solving a complex problem by breaking it down into a collection of simple subproblems.——Wiki
动态规划的本质是对问题状态的定义和状态转移方程的定义。
动规是通过拆分问题。定义状态与状态之间的关系,使得问题能够以递归(或者说分治)的方法去解决。
拆分问题就是定义状态和状态转移矩阵。

1.状态

i.e. 给定一个数列,长度为N,求这个数列的最长递增子序列的长度。

要解决这个问题,我们要首先定义这个问题和这个问题的子问题,所以我们来重新定义这个问题:
给定一个数列,长度为N,
Fk F k 为以数列第k项结尾的最长递增子序列的长度。
F1,,FN F 1 , ⋯ , F N 中的最大值。

显然,这个问题与原问题等价。
对于 Fk F k 来讲, F1,,FN F 1 , ⋯ , F N 都是 Fk F k 的子问题, Fk F k 就是状态。
状态的定义不只一种。

1.状态转移方程

上述状态定义好之后,状态和状态之间的关系式就叫做状态转移方程。

上述问题的状态转移方程为:
k=1时 F1=1 F 1 = 1 (根据状态定义导出边界情况)
k>1时 Fk=max(Fi+1Ak>Ai,i[1,,k1]) F k = m a x ( F i + 1 ∣ A k > A i , i ∈ [ 1 , ⋯ , k − 1 ] ) ,设A为题中数列。

用文字解释一下就是:以第k项结尾的LIS的长度是:保证第i项比第k项小的情况下,以第i项结尾的LIS长度加1的最大值,取遍i的所有值(i小于k)。

由此可以看出,状态转移方程就是定义了问题和子问题之间的关系。状态转移方程就是带有条件的递推式。

使用动态规划的条件:
子问题有重叠,每个阶段的最优状态可以从之前某个阶段的某个或某些状态直接得到(最优子结构),而不管之前这个状态是如何得到的(无后效性)。

(动态规划和递归是两种不同的方法,不可混为一谈。动态规划主要应用于解决子问题重叠的情况,相对于动态规划,分治算法会计算一些已经计算过的值,重复大量已经计算好的部分,导致效率比较低。而动态规划通常的做法是会生成一个Map,计算过项目-值都会保存在这个Map中,当我们遇到下一个子问题时,我们会首先得去这个Map中查看是这个子问题是否已经计算过了,如果计算过了直接返回结果,否则我们按照计算这个子问题,在计算完成后更新我们的Map。这样我们就真正的做到了每个子问题都只计算一次。当然有些子问题并没有重叠的部分,也就只能选择分治算法了。两者和而不同,各有自己应用的情景。)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值