算法学习笔记——动态规划:核心思想与求解步骤

动态规划核心思想

首先要明确,只要涉及求最值,一定是穷举所有可能,然后比较得出最值,穷举可以是回溯(暴力穷举)、递归等,满足重叠子问题等特征时,可以优化穷举的效率,也就是动态规划

  • 动态规划本质就是将问题拆分为子问题+穷举,但不是暴力穷举,其思想源于暴力穷举,但使用了“备忘录”或DP Table进行优化,从而利用子问题解决大问题,此外再无奥妙可言(思考如何穷举->追求聪明地穷举)
  • 动态规划一般都涉及表格,就是用一个表记录所有已解决子问题的解,并在此后尽可能的利用这些子问题的解,进而解决总问题
  • 动态规划三要素:重叠子问题、最优子结构、状态转移方程

找状态转移方程的方法

找状态转移方程,核心问题就是状态、选择、DP数组的定义

  1. 思考问题有什么“状态”,即算法推进过程中会改变的变量
    一般有几个状态量,dp数组就需要几个维度
  2. 思考对于每个状态,有什么“选择”使状态改变
    ps. 技巧:类比数学归纳思想,假定已知dp[0]...dp[i-1],问自己怎么通过这些结果算出dp[i],最后将这个模式套入所有dp的推导即可
  3. 思考如何用DP数组/函数的含义来表现“状态”和“选择”
    一般DP数组的下标(或DP函数的参数)就是2中的“状态”,DP数组保存的变量就是要优化的指标
  4. 思考问题的base case(最简单情况)是什么

一般而言,动态规划就是将某个指标最大化,这个值的最优,由子问题的最优来实现,子问题通常就是单元格的值,而不断进行“转移”的状态就是单元格的坐标,由此,求解每个单元格的子问题,最终求解整个问题

进一步优化:状态压缩

  • 进一步的,写出完整动态规划解法后,如果dp表中各单元格的计算只依赖相邻的单元格,还可以进行状态压缩(仅用于降低空间复杂度,但可读性大大降低)
    例如,二维dp表,每行只依赖上一行,就可以压缩为一维dp表
    甚至每格依赖左上、上、左的情况,也可以压缩

DP问题一般求解步骤

技巧:

  • 动态规划中,需要将某个指标最大化
  • 这个要优化的值,通常就是单元格的值
  • 由此确定子问题,找出DP Table网格的坐标轴

套路:遇到求最值问题,先思考最优子结构(用子问题解决大问题),写出状态转移方程,就对应暴力解,从暴力解就可看出有无重叠子问题,如果有就用dp数组优化

步骤:

  1. 找出“状态”和“选择”
  2. 明确dp数组/函数的定义
  3. 寻找“状态”间的关系(找状态转移方程)
    技巧:找状态转移方程需要归纳思维,类比数学归纳思想,假定已知dp[0]...dp[i-1],问自己怎么通过这些结果算出dp[i],最后将这个模式套入所有dp的推导即可
    技巧:先找出base case和最终答案位置,根据相对位置关系猜测状态转移方程

如果这步无法完成,可能是由于dp数组含义定义不恰当,需要重新定义;也可能时dp给出的信息不够,不足以推出下一步,需要将dp扩大为二维/三维数组

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值