背包问题
- 常见的背包问题类型(大厂面试重点掌握01背包和完全背包即可)
- 题目描述:有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品能用*次,求解怎么装物品使得装入背包里物品价值总和最大。
01背包
https://programmercarl.com/%E8%83%8C%E5%8C%85%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%8001%E8%83%8C%E5%8C%85-1.html
视频讲解:https://www.bilibili.com/video/BV1cg411g7Y6
- 题目描述:有n件物品和一个最多能背重量为w 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。
- 动规五部曲
- 二维dp数组dp[i][j]
- 其中i代表有前 i 个物品可选,j代表背包的容量,dp值代表对应的最大价值
- 递推公式
- 当前 i 和 j 对应的最大价值为
装第i个物品
和不装第i个物品
两种情况里的较大值 - 其中装第i个物品对应的dp值为
dp[i - 1][j - weight[i]] + value[i]
,weight[i]表示第i个物品的重量,value[i]代表第i个物品的价值 - 不装第i个物品对应的dp值为dp[i - 1][j]
- 即
dp[i][j] = max(dp[i - 1][j - weight[i]], dp[i - 1][j] + value[i])
- 当前 i 和 j 对应的最大价值为
- 二维dp数组的初始化
- 当把二维dp数组画图表示出来后,可以发现dp[i][j]的值仅由其上方或左上方的元素值决定,因此需要把dp数组的第一行和第一列进行初始化
- 第一行的初始化(第一行对应只有物品1和背包容量递增的情况):由于是01背包,所以在背包容量 < 物品1重量时,初始化为0,当背包容量 >= 物品1重量时,均初始化为物品1的价值
- 第一列的初始化(即物品由少到多但背包容量为0的情况):全部初始化为0
- 遍历顺序
- 内外层for循环是先遍历物品还是背包容量都可以,因为二维数组图里无论哪种遍历方式都满足当前元素的上方和左上方元素已有值
- 每层for循环从小到大遍历
- 无需打印
- 二维dp数组dp[i][j]