解决01背包问题 | 豆包MarsCode AI 刷题
问题描述
一个旅行者外出旅行时需要将 n 件物品装入背包,背包的总容量为 m。每个物品都有一个重量和一个价值。你需要根据这些物品的重量和价值,决定如何选择物品放入背包,使得在不超过总容量的情况下,背包中物品的总价值最大。
给定两个整数数组 weights 和 values,其中 weights[i] 表示第 i 个物品的重量,values[i] 表示第 i 个物品的价值。你需要输出在满足背包总容量为 m 的情况下,背包中物品的最大总价值。
解决思路
首先搞懂01背包的通用解法,01背包的精髓就在于:dp[i]的计算包含两种情况,选当前元素和不选当前元素
其次搞清楚01背包用二维数组解法和一维数组解法的不同,二维dp数组和一维dp数组有哪些不同:因为一维数组少了一个维度,所以很可能由于操作不当导致状态被覆盖,使用一维dp数组时要倒序遍历背包容量(dp[j]依赖于dp[j-weight[i]],如果j从小到大遍历,dp[j-weight[i]]可能被当前轮次的更新所覆盖,而已经不是上一次的状态了)、先遍历物品再遍历背包容量且顺序不可交换(否则每次的背包容量都可选择所有的物品,这是完全背包问题而非01背包),二维数组因为有i这个维度,能够确保不同物品间的轮次互不影响,所以没这么多限制
这道题我选择使用一维dp数组来解决,dp[j]表示容量为j的背包所能装的物品的最大价值
算法步骤
- 初始化:创建一个长度为
m + 1的数组dp,并将所有元素初始化为0。 - 状态转移:
- 对于每个物品
i,从背包容量m开始,倒序遍历到当前物品的重量weights[i]。 - 对于每个容量
j,更新dp[j]的值,使其为当前值和放入当前物品后的最大值。
- 对于每个物品
- 推导出结果:最终
dp[m]就是容量为m的背包所能装的最大价值。
通过动态规划的思想逐步更新 dp 数组,最终得到容量为 m 的背包所能装的最大价值。这个方法的时间复杂度为 O(n * m),空间复杂度为 O(m)。