动态规划

作者: topshi | 来源:发表于2019-05-02 21:41 被阅读0次

动态规划题目特点

1. 计数
  • 有多少种方式走到右下角
  • 有多少种方法选出k个数使得和是sum
2.求最大最小值
  • 从左上角走到右下角路径的最大数字和
  • 最长上升子序列长度
3.求存在性
  • 取石子游戏,先手是否必胜
  • 能不能选出k个数使得和是sum

动态规划四个组成部分:

  • 确定状态
    • 研究最优策略的最后一步
    • 化为子问题
  • 转移方程
    • 根据子问题定义直接得到
  • 初始条件和边界情况
  • 计算顺序
    • 利用之前的计算结果

最值型动态规划

Coin Change
假设你有三种硬币,分别面值2元,5元和7元,每种硬币都有足够多,买一本书需要27元,如何用最少的硬币组合正好付清,不需要对方找钱。

动态规划组成部分一:确定状态

  • 状态是动态规划的核心
  • 解动态规划时需要定义一个数组,数组的每一个元素f[i]或者f[j][j]代表什么
  • 确定状态需要两个意识:
    • 最后一步
    • 子问题

最后一步
1-不知道最优策略,但最优策略肯定是K枚硬币a_1,a_2,...,a_k面值加起来是27
2-所以肯定有一枚最后的硬币:a_k
  关键点1:不关心前面k-1枚硬币如何拼出27-a_k,甚至不知道a_k和K,但是确定了前面的硬币拼出了27-a_k
  关键点2:因为是最优策略,所以拼出27-a_k的硬币数一定要最少,否则矛盾。
子问题
1 - 需要求出最少用多少枚硬币可以拼出27-a_k
2 - 原问题是最少用多少枚硬币拼出27
3 - 原问题转化成了一个规模更小的子问题:27-a_k
4 - 设状态f(X) = 最少用多少枚硬币拼出X
最后一枚硬币只可能是2,5或7
a_k == 2f(27)应该是f(27 - 2) + 1(加上最后的一枚硬币2)
a_k == 5f(27)应该是f(27 - 5) + 1(加上最后的一枚硬币5)
a_k == 7f(27)应该是f(27 - 7) + 1(加上最后的一枚硬币7)
要求最少的硬币数:
f(27) = min{f(27 - 2), f(27 - 5), f(27 - 7)} + 1

动态规划组成部分二:转移方程

  • 设状态f(X) = 最少用多少枚硬币拼出X
  • 对于任意Xf(27) = min{f(27 - 2), f(27 - 5), f(27 - 7)} + 1

动态规划组成部分三:初始条件和边界情况

  • X < 0时,f(X) = +\infty
  • 初始条件:f(0) = 0

动态规划组成部分三:计算顺序

  • 初始条件:f(0) = 0
  • 然后计算f(1),f(2),...,f(27)
  • 大多数情况都是从小到大地算,这样当算f(x)时,前面的f(x-2),f(x-5)和f(x-7)都已经算过了。

求最值型动态规划小结

  • 1.确定状态
    • 最后一步(最优策略中使用的最后一枚硬币a_k
    • 化成子问题(最少的硬币拼出更小的面值27-a_k
  • 2.转移方程
    • f(X) = min{f(X - 2), f(X - 5), f(X - 7)} + 1
  • 3.初始条件和边界情况
    • f(0) = 0,如果不能拼出Xf(X) = +\infty
  • 4.计算顺序
    • f(0),f(1),...

计数型动态规划

Unique Paths

给定m行n列的网格,有一个机器人从左上角(0, 0)出发,每一步可以向下或者向右走一步,问有多少种不同的方式走到右下角

动态规划组成部分一:确定状态

  • 最后一步:机器人走到右下角之前的最后一步:向右或者向下
  • 右下角坐标为(m - 1, n - 1),那么前一步机器人一定是在(m - 2, n - 1)或者(m - 1, n - 2)
  • 子问题 ——从左上角走到(m - 2, n - 1)和从左上角走到(m - 1, n - 2);假设从左上角走到(m - 2, n - 1)有X种方式,从左上角走到(m - 1, n - 2)有Y种方式,那么走到(m - 1, n - 1)就有X+Y种方式。
    问题转化为机器人有多少种方式从左上角走到(m - 2, n - 1)和(m - 1, n - 2)
  • 状态:设f[i][j]为机器人有多少种方式从左上角走到(i,j)

动态规划组成部分二:转移方程

  • 对于任意坐标(i,j)f[i][j] = f[i - 1][j] + f[i][j - 1]

动态规划组成部分三:初始条件和边界情况

  • 初始条件:f[0][0] = 1,机器人只有一种方式到左上角
  • 边界情况:i = 0或j = 0,则前一步只能有一个方向过来

动态规划组成部分四:计算顺序

  • f[0][0] = 1
  • 计算第0行:f[0][0],f[0][1],...,f[0][n-1]
  • 计算第1行:f[1][0],f[1][1],...,f[1][n-1]
  • ...
  • 计算第m-1行:f[m-1][0],f[m-1][1],...,f[m-1][n-1]
  • 答案是f[m-1][n-1]
    时间复杂度和空间复杂度都是O(mn)

存在性型动态规划

n块石头分别在x轴的0,1,...,n-1位置,一只青蛙在石头0,想跳到石头n-1,如果青蛙在第i块石头上,它最多可以向右跳距离a_i,问青蛙能否跳到石头n-1

动态规划组成部分一:确定状态

  • 最后一步:如果青蛙能跳到最后一块石头n-1,考虑它跳的最后一步是从石头i跳过来的,i < n-1
  • 需要满足两个条件:1. 青蛙可以跳到石头i 2.最后一步不超过跳跃的最大距离:n-1-i<=a_i
  • 子问题——青蛙能不能跳到石头i(i<n-1)
  • 状态:设f[j]表示青蛙能不能跳到石头j

动态规划组成部分二:转移方程

  • f[j]表示青蛙能不能跳到石头jf[j] = OR_{0<=i<j}(f[i] \&\& (i + a[i] >= j))

动态规划组成部分三:初始条件和边界情况

  • f[j]表示青蛙能不能跳到石头j
  • 初始条件:f[0] = True,青蛙一开始就在石头0

动态规划组成部分四:计算顺序

  • 初始化f[0] = True
  • 计算f[1],f[2],...,f[n-1]
  • 答案是f[n-1]
    时间复杂度:O(n^2),空间复杂度:O(n)

相关文章

网友评论

    本文标题:动态规划

    本文链接:https://www.haomeiwen.com/subject/vkwbnqtx.html