基础
01背包: 有n种物品,每种物品只有一个 完全背包: 有n种物品,每种物品有无限个 多重背包: 有n种物品,每种物品数量各不相同
刷题
码卡网 46. 携带研究资料
二维
动规五部曲:
- 确定dp数组:
来源: www.bilibili.com/video/BV1pY…
-
确定递归公式: dp[i][j] = max(dp[i-1][j], 当前物品价值 value[i-1] + dp[i-1][j-value[i-1]] 这里dp[i-1] 是因为一个物品只能取一次)
-
确定dp数组初始化:dp[0][i]是都是0,dp[i][0]都是0
为什么第一行没有物品且都是0? 因为递推公式dp[i][j]需要dp[i-1][j]的值,
- 确定遍历顺序,从左到右,从上到下
- 打印dp数组
一维 滚动数组
动规五部曲:
-
确定dp数组: 使用一维数组,每次只保留dp[j],j为背包能承受的最大重量。
-
确定递推公式: dp[j] = max(dp[j], dp[j-weight[i]] + value[i])
-
确定dp初始化:全部是0,因为递推公式中会和dp[j]作比较,dp[j] >= 0 ,所以初始化为0最合适
-
确定遍历顺序:先遍历物品种类,再从背包最大重量倒叙排列,因为递推公式中,需要dp[j-weight[i]]的值,如果按照背包大小顺序遍历,后面的值会使用到前面覆盖的值,而拿不到上一个物品的dp[j-weight[i]]
-
打印dp数组
-
分割等和子集
二维:
动规五部曲:
- 确定dp数组:
| - | 和=0 | 和=1 |
|---|---|---|
| 不取任何数字 | 0 | 0 |
| 取第一个数字(1) | 从取出的数字加上的最大值 max == 和(0) | |
| 取第二个数字(5) |
- 确定递推公式: dp[i][j] = dp[i][j-1] || dp[i-1][j-value[i-1]]
- 确定dp初始化: dp[i][0] = true. dp[0][j] = false (j!=0)
- 确定遍历顺序: 先从左往右,再从上到下
- 打印dp数组
一维:
- 确定dp数组:把二维转为一维 dp[j] 代表 总和为j,目前递推的组合中有没有能够加上正好等于 j 的组合
- 确定递推公式: dp[j] = dp[j-nums[i]]
- 确定dp初始化: dp[0] = true dp[i]=false
- 确定遍历顺序: 从右向左遍历
- 打印dp数组
总结
很多背包问题都可以从二维数组转化为一维的dp数组,会简化一定的代码量,但是初学还是先从二维dp数组开始思考,会更容易