
1) 【一句话结论】:0-1背包问题通过动态规划定义状态dp[i][j](前i个物品装容量j的最大价值),状态转移为dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]),时间复杂度为O(nW),适用于物品不可分割的背包问题。
2) 【原理/概念讲解】:动态规划解决0-1背包的核心是“状态定义+状态转移+边界条件”。
dp[i][j]表示前i个物品(物品1到物品i)装入容量为j的背包所获得的最大价值。dp[i-1][j];j-w[i],价值为前i-1个物品装容量j-w[i]的最大价值加上当前物品价值,即dp[i-1][j-w[i]] + v[i];dp[i][j]。dp[0][j]=0(无论背包容量多大,价值为0);dp[i][0]=0(无论有多少物品,价值为0)。3) 【对比与适用场景】:
| 模型 | 0-1背包 | 完全背包 |
|---|---|---|
| 定义 | 每个物品仅能使用1次,不可分割 | 每个物品可无限使用,不可分割 |
| 状态转移 | dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]) | dp[i][j] = max(dp[i-1][j], dp[i][j-w[i]] + v[i]) |
| 时间复杂度 | O(nW) | O(nW)(内层循环从0到j-w[i]) |
| 适用场景 | 珠宝、书籍、电子产品(不可重复使用) | 糖果、饮料(可重复购买) |
| 注意点 | 确保物品索引和容量索引正确,避免越界 | 内层循环方向影响计算顺序(通常从0到j-w[i]) |
4) 【示例】:
假设有3个物品,重量w=[2,3,4],价值v=[3,4,5],背包容量W=5。
dp[0][j]=0(所有j),dp[i][0]=0(所有i)。dp[1][2]=max(0, dp[0][2]+3)=3(选物品1)。dp[2][5]=max(dp[1][5], dp[1][2]+4)=max(0, 3+4)=7(选物品1和物品2,重量2+3=5,价值3+4=7)。dp[3][5]=max(dp[2][5], dp[2][1]+5)=max(7, 0)=7(最终最大价值为7)。5) 【面试口播版答案】:
“0-1背包问题用动态规划解决,核心是定义状态dp[i][j]表示前i个物品装进容量为j的背包的最大价值。状态转移方程是dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i]),其中i从1到n,j从0到W。边界条件是dp[0][j]=0(0个物品时,任何容量价值为0),dp[i][0]=0(容量为0时,任何物品价值为0)。时间复杂度是O(nW),因为双重循环遍历物品和容量。举个例子,物品重量[2,3,4],价值[3,4,5],容量5,通过状态转移计算得到最大价值为7(选物品1和物品2,重量2+3=5,价值3+4=7),这就是0-1背包问题的解法。”
6) 【追问清单】:
dp[j]表示当前容量下的最大价值,因为当前状态只依赖上一行(前i-1个物品),空间复杂度可降为O(W)。dp[0][j]=0(无物品时,任何容量价值为0),dp[i][0]=0(容量为0时,任何物品价值为0),确保初始状态正确。long long存储避免溢出;若n或W很大,可考虑近似算法(如贪心或动态规划优化),但核心状态转移不变。7) 【常见坑/雷区】:
dp[i][j]误解为“i个物品装j的”,转移时索引混乱,导致计算错误。dp[0][j]或dp[i][0],导致结果错误。j-w[i] < 0时未判断,导致数组访问错误。