DP学习总结

DP总结

一.状态表示

dp中首要的就是定义一个dp表,一般根据具体题目再来具体分析,接下来列出一些常见的类型:

  • dp[i] : 以i位置结束或者开始,……
  • dp[i][j] : 以i位置以及j位置的元素为结尾,……
  • dp[i] : 以[0,i] 区间上,……
  • 定义多个dp表,来表示不同情况,比如dp[i][1/2/3]表示三种不同情况
  • dp[i][j] : a 字符串 [0, j] 区间内的xx(⼦串),能否匹配字符串 b 的 [0, i] 区间内的xx(字串), ……(两数组的dp问题中常用)
  • dp[i][j] : 从前 i 个物品中挑选,总体积不超过 j ,所有的选法中,能挑选出来的最⼤价值。(背包问题,有两个条件)//选or不选
  • dp[i][j][k] 表⽰:从前 i 个字符串中挑选,字符 0 的个数不超过 j ,字符 1 的个数不超过 k ,所有的选法中,最⼤的⻓度(适用于三个要求的,例如完全背包)

二.状态转移方程

不要背状态转移⽅程,因为题型变化之后,状态转移⽅程就会跟着变化。我们要记住的是分析问题的模式。⽤这种分析问题的模式来解决问题

​ 但很多dp题,都可以从最后一步,最后一个来入手

  • 线性 dp 状态转移⽅程分析⽅式,⼀般都是根据「最后⼀步」的状况,来分情况讨论
  • 根据「最后⼀个位置」的元素,结合题⽬的要求,分情况讨论

三.初始化

根据「状态转移⽅程」来决定

tips:

  1. 在最前⾯加上⼀个辅助结点,帮助我们初始化。使⽤这种技巧要注意两个点:

    i. 辅助结点⾥⾯的值要保证后续填表是正确的;

    ii. 下标的映射关系。

  2. 在处理字符串时,要注意

    i. 「空串」是有研究意义的,因此我们将原始 dp 表的规模多加上⼀⾏和⼀列,表⽰空串。

    ii. 引⼊空串后,⼤⼤的⽅便我们的初始化。

    iii. 但也要注意「下标的映射关系」,以及⾥⾯的值要「保证后续填表是正确的」。

    iiii.如果dp多开了一行一列,字符串也可以多加一个空,使字符串下标与dp相对应 eg: s = ‘ ’ + s;

四.填表顺序

根据「状态转移方程」来决定,从上往下,从左往右,先上再右等各类情况

五.返回值

根据「状态表⽰」来决定,据题意分析,一般较易

注意事项:有的题目在问返回值时,要注意你的dp表定义时,里面有没有重复的,如果有记得去重

六.技巧

动态规划没有固定的模板,但有一些思想和式子也有助于我们做题:

  1. 正难则反

  2. 当我们发现,计算⼀个状态的时候,需要⼀个循环才能搞定的时候,我们要想到去优化。优化的⽅向就是⽤⼀个或者两个状态来表⽰这⼀堆的状态。通常就是把它写下来,然后⽤数学的⽅式做⼀下等价替换,推导过程如下

    eg : 状态转移⽅程为:dp[i][j] = dp[i][j - 1] || dp[i - 1][j - 1] || dp[i - 2][j - 1] …

    我们发现 i 是有规律的减⼩的,因此我们去看看 dp[i - 1][j] :dp[i - 1][j] = dp[i - 1][j - 1] || dp[i - 2][j - 1] || dp[i - 3][j - 1] … 我们惊奇的发现, dp[i][j] 的状态转移⽅程⾥⾯除了第⼀项以外,其余的都可以⽤ dp[i - 1][j] 替代。
    因此,我们优化我们的状态转移⽅程为: dp[i][j] = dp[i][j - 1] || dp[i - 1][j]

    实际上,就是将i换成了i-1,因为这题j是固定所以换i,如果有题目j不固定,i是固定的话,也可以换j

    eg2:dp[i][j] = min(dp[i - 1][j], dp[i][j - coins[i]] + 1) 。

    就是相当于把第⼆种情况 dp[i - 1][j - coins[i]] + 1 ⾥⾯的 i - 1 变成 i 即可。

  3. 有的题目需要反复检查数据时,可以考虑⽤哈希表做优化,甚至直接在哈希表中做动态规划。

  4. 背包问题解决的是组合,不是排列问题。排列问题要求有序 ,组合是无序的。

  5. 空间优化:

    背包问题基本上都是利⽤「滚动数组」来做空间上的优化:

    ​ i. 利⽤「滚动数组」优化;

    ​ ii. 直接在「原始代码」上修改。

    在01背包中,优化一般都是

    ​ i. 删掉第⼀维;

    ​ ii. 修改第二层循环的遍历顺序即可。

    在完全背包(可以拿无限多个)里则是:

    ​ i. 仅需删掉所有的横坐标

    对于⼆维费⽤的 01 背包类型的,我们的优化策略是:

    ​ i. 删掉第⼀维;

    ​ ii. 修改第⼆层以及第三层循环的遍历顺序即可

  6. 我们一般为了方便会给dp表多开一行多开一列,但在有的题目里,例如求最大最小值的,如果不初始化好的话,可能会影响到后面的结果,所以推荐用0x3f3f3f3f来初始化,既能表示出最大最小的效果,又能进行±运算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值