01背包最大价值问题 | 豆包MarsCode AI刷题

58 阅读2分钟

问题描述

一个旅行者外出旅行时需要将 n 件物品装入背包,背包的总容量为 m。每个物品都有一个重量和一个价值。你需要根据这些物品的重量和价值,决定如何选择物品放入背包,使得在不超过总容量的情况下,背包中物品的总价值最大。 给定两个整数数组 weights 和 values,其中 weights[i] 表示第 i 个物品的重量,values[i] 表示第 i 个物品的价值。你需要输出在满足背包总容量为 m 的情况下,背包中物品的最大总价值。

思路解析

这个问题是一个经典的0/1背包问题,我们通常使用动态规划来解决。以下是解题的思路:

目标: 在给定背包容量 m 下,选择的物品使得总重量不超过 m,同时我们需要让背包中的总价值最大。

特性:

  1. 每个物品要么选,要么不选。并不是每个物品都需要进行选择
  2. 动态规划的核心是 决策选择状态转移

动态规划的定义

假设 数组dp[j] 是表示在容量 j 下,可以获得的最大价值。因此,我们的最终目标是求 dp[m]

状态转移方程

对于每个物品 i:

  1. 如果不选第 i个物品,价值为 dp[j](继承上一状态)。
  2. 如果选择第 i 个物品,价值为 dp[j - weights[i]] + values[i](减去重量,加上价值)。 状态转移的公式如下:
dp[j]=max(dp[j],dp[jweights[i]]+values[i])dp[j]=max(dp[j],dp[jweights[i]]+values[i])dp[j]=max(dp[j],dp[jweights[i]]+values[i])dp[j]=max⁡(dp[j],dp[j−weights[i]]+values[i])dp[j] = \max(dp[j], dp[j - weights[i]] + values[i])dp[j]=max(dp[j],dp[j−weights[i]]+values[i])

初始化

  • 初始 dp[j] 全部为 0,因为没有物品时,任何容量下价值都是 0。

优化方向

动态规划通常通过二维数组表示:dp[i][j] 表示前 i 个物品在容量 j 下的最大价值。
但可以优化为一维数组 dp[j],从后向前遍历容量 j,避免覆盖影响。

代码详解

  1. 初始化:
    • 创建一维数组 dp,大小为 m+1,所有值初始化为 0。
  2. 物品选择:
    • 外层循环遍历物品,内层从容量 m 向 weights[i]倒序更新。
    • 倒序更新避免覆盖之前未处理的数据。
  3. 更新规则:
    • 每次取当前状态和加入当前物品后的状态的较大值。

复杂度分析

  1. 时间复杂度:
    • 外层遍历物品 O(n),内层遍历容量 O(m),总复杂度为 O(n⋅m)。
  2. 空间复杂度:
    • 使用一维数组 dp,复杂度为 O(m)。