Day35 动态规划 Part03

54 阅读2分钟

基础

01背包: 有n种物品,每种物品只有一个 完全背包: 有n种物品,每种物品有无限个 多重背包: 有n种物品,每种物品数量各不相同

image.png

刷题

码卡网 46. 携带研究资料

kamacoder.com/problempage…

二维

image.png

动规五部曲:

  1. 确定dp数组:

image.png

来源: www.bilibili.com/video/BV1pY…

  1. 确定递归公式: dp[i][j] = max(dp[i-1][j], 当前物品价值 value[i-1] + dp[i-1][j-value[i-1]] 这里dp[i-1] 是因为一个物品只能取一次)

  2. 确定dp数组初始化:dp[0][i]是都是0,dp[i][0]都是0

为什么第一行没有物品且都是0? 因为递推公式dp[i][j]需要dp[i-1][j]的值,

  1. 确定遍历顺序,从左到右,从上到下
  2. 打印dp数组

一维 滚动数组

image.png

动规五部曲:

  1. 确定dp数组: 使用一维数组,每次只保留dp[j],j为背包能承受的最大重量。

  2. 确定递推公式: dp[j] = max(dp[j], dp[j-weight[i]] + value[i])

  3. 确定dp初始化:全部是0,因为递推公式中会和dp[j]作比较,dp[j] >= 0 ,所以初始化为0最合适

  4. 确定遍历顺序:先遍历物品种类,再从背包最大重量倒叙排列,因为递推公式中,需要dp[j-weight[i]]的值,如果按照背包大小顺序遍历,后面的值会使用到前面覆盖的值,而拿不到上一个物品的dp[j-weight[i]]

  5. 打印dp数组

  6. 分割等和子集

leetcode.cn/problems/pa…

image.png

二维:

动规五部曲:

  1. 确定dp数组:
-和=0和=1
不取任何数字00
取第一个数字(1)从取出的数字加上的最大值 max == 和(0)
取第二个数字(5)
  1. 确定递推公式: dp[i][j] = dp[i][j-1] || dp[i-1][j-value[i-1]]
  2. 确定dp初始化: dp[i][0] = true. dp[0][j] = false (j!=0)
  3. 确定遍历顺序: 先从左往右,再从上到下
  4. 打印dp数组

一维:

image.png

  1. 确定dp数组:把二维转为一维 dp[j] 代表 总和为j,目前递推的组合中有没有能够加上正好等于 j 的组合
  2. 确定递推公式: dp[j] = dp[j-nums[i]]
  3. 确定dp初始化: dp[0] = true dp[i]=false
  4. 确定遍历顺序: 从右向左遍历
  5. 打印dp数组

总结

很多背包问题都可以从二维数组转化为一维的dp数组,会简化一定的代码量,但是初学还是先从二维dp数组开始思考,会更容易