解决01背包问题 | 豆包MarsCode AI 刷题

64 阅读2分钟

解决01背包问题 | 豆包MarsCode AI 刷题

问题描述

一个旅行者外出旅行时需要将 n 件物品装入背包,背包的总容量为 m。每个物品都有一个重量和一个价值。你需要根据这些物品的重量和价值,决定如何选择物品放入背包,使得在不超过总容量的情况下,背包中物品的总价值最大。

给定两个整数数组 weightsvalues,其中 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的背包所能装的物品的最大价值

算法步骤

  1. 初始化:创建一个长度为 m + 1 的数组 dp,并将所有元素初始化为0。
  2. 状态转移:
    • 对于每个物品 i,从背包容量 m 开始,倒序遍历到当前物品的重量 weights[i]
    • 对于每个容量 j,更新 dp[j] 的值,使其为当前值和放入当前物品后的最大值。
  3. 推导出结果:最终 dp[m] 就是容量为 m 的背包所能装的最大价值。

通过动态规划的思想逐步更新 dp 数组,最终得到容量为 m 的背包所能装的最大价值。这个方法的时间复杂度为 O(n * m),空间复杂度为 O(m)