2020-12-26 软件技术部 动态规划培训

动态规划概念

动态规划过程是:每次决策依赖于当前状态,又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的,所以,这种多阶段最优化决策解决问题的过程就称为动态规划。

什么是动态规划?

将一个大问题转化成几个小问题;
求解小问题;
推出大问题的解。

总而言之:大事化小,小事化了

动态规划题目特点

  1. 计数
  • 地图中小人有多少种方式走到右下角

  • 有多少种方法选出k个数使得和是sum

  1. 求最大值最小值问题
  • 从左上角走到右下角路径的最大数字和

  • 最长上升子序列

  1. 求存在性
  • 取石子游戏,先手是否必胜

  • 能不能选出k个数使得和是sum

以上仅为部分常见动态规划问题,可照此方向进行初步动态规划理解

动态规划题目初级分类

  1. 坐标型动态规划

  2. 序列型动态规划

  3. 划分型动态规划

动态规划解题步骤

步骤one:确定状态

  • 状态在动态规划中的作用属于定海神针

  • 简单的说,解动态规划的时候需要开一个数组,数组的每个元素f[i]代表什么,f[i]即为状态

  • 确定状态需要两个意识:

  • 最后一步

  • 子问题

最后一步:研究最优策略的最后一步

子问题:把一个原问题(大问题)化为子问题(小问题)

步骤two:转移方程

根据子问题定义直接得到即可因题目而异(此为难点,亦为解决此题重点与核心所在)

步骤three:初始条件和边界

根据题目具体分析

切记:细心,考虑周全

步骤four:计算顺序

因需要利用前面的计算结果,故一般顺序为从左到右,从上到下

具体题目案例分析

one

你有三种硬币,分别面值为2元,5元和7元,每种硬币都有足够多

买一本书需要27元

如何使用最少的硬币组合正好付清,不需要对方找钱?

本题是一种最值型动态规划

解题思路:

  1. 确定状态:
  • 虽然我们不知道最优策略是什么,但是最优策略肯定是K枚硬币a1,a2,…,ak面值加起来是27

  • 所以一定有最后一枚硬币:ak

  • 除去这最后一枚硬币,前面硬币面值加起来是27-ak

(关键点1: 我们不关心前面k-1枚硬币是怎么拼出27-ak的,而且我们现在甚至不知道ak和k,但是我们确定前面的硬币拼出了27-ak。关键点2: 因为是最优策略,所以拼出27-ak的硬币数量一定要最少,否则这就不是最优策略了)

  • 所以我们就要求:最少用多少枚硬币可以拼出27-ak

  • 原问题是最少用多少枚硬币拼出27

  • 我们将原问题转化成了一个子问题,而且规模更小: 27-ak

  • 为了简化定义,我们设状态f(x) = 最少多少枚硬币拼出x

  1. 转移方程:
  • 设状态f[X] = 最少用多少枚硬币拼出X

  • 对于任意X,在这里插入图片描述

  1. 初始条件和边界
  • 初始条件f[0] = 0

  • 如果不能拼出Y,就定义f[Y] = 正无穷

  • 例如f[-1] = f[-2] = …… = 正无穷

  • 所以f[1] = min{f[-1]+1,f[-4]+1,f[-6]+1}=正无穷,表示无法拼出1

  1. 计算顺序:

    f[1],f[2],f[3]…f[27]

    当我们计算到f[X]时,f[X-2],f[X-5],f[X-7]都已经得到结果了

two

给定m行n列的网格,有一个机器人从左上角(0, 0)出发,每一步可以向下或者向右走一步

问有多少种不同的方式走到右下角

计数型动态规划
在这里插入图片描述

解题思路:

  1. 确定状态:
  • 最后一步:无论机器人用何种方式到达右下角,总有最后挪动的一步:向右或者向下

  • 那么设右下角坐标为(m-1,n-1)

  • 那么机器人前一步一定是在(m-2,n-1)或者(m-1,n-2)

  • 子问题

  • 问题转化为机器人有多少种方式从左上角走到(m-2,n-1)和 (m-1,n-2)

  • 原问题是问有多少种方式从左上角走到(m-1,n-1)

  • 状态:设f[i][j]为机器人有多少种方式从左上角走到(i, j)

  1. 转移方程:
  • 如果机器人有X种方式从左上角走到(m-2,n-1),有Y种方式从左上角走到(m-1,n-2),则机器人有X+Y种方式走到(m-1,n-1)

  • 对于任意一个格子(i, j):

    f[i][j] = f[i-1][j] + f[i][j-1]

  1. 初始条件和边界:
  • 初始条件:f[0][0] = 1, 因为机器人只有一种方式到左上角

  • 边界情况: i=0 或 j=0, 则前一步只能有一个方向过来->f[i][j] = 1

  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]

three

有n块石头分别在x轴的0, 1, …, n-1位置

一只青蛙在石头0,想跳到石头n-1

如果青蛙在第i块石头上,它最多可以向右跳距离为ai

问青蛙能否跳到石头n-1

存在性动态规划

例子:

输入: a=[2, 3, 1, 1, 4] 输出: True

输入: a=[3, 2, 1, 0, 4] 输出: False

  1. 确定状态:
  • 最后一步:如果青蛙能跳到最后一块石头n-1,我们考虑它跳的最后一步

  • 这一步是从石头i跳过来, i<n-1

  • 这需要两个条件同时满足:

    1. 青蛙可以跳到石头i
    2. 最后一步不超过跳跃的最大距离: ai >= n-1-i
    
  • 子问题

  • 我们需要知道青蛙能不能跳到石头i (i<n-1)

  • 原问题要求青蛙能不能跳到石头n-1

  • 状态:设f[j]表示青蛙能不能跳到石头j

  1. 转移方程:

在这里插入图片描述

  1. 初始条件和边界:
  • 初始条件:f[0] = True, 因为青蛙一开始就在石头0
  1. 计算顺序:
  • 计算f[1], f[2], …, f[n-1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值