1. 二维DP解法分析
在01背包问题中,我们有一组物品,每个物品有自己的重量和价值,我们需要选择一些物品放入背包中,使得背包的总重量不超过背包容量,且价值最大化。
首先,我们定义一个二维数组 dp[i][j]
,其中 dp[i][j]
表示在考虑前 i
个物品,且背包容量为 j
的情况下,背包中所能装下的最大价值。
状态转移方程为:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]] + value[i])
其中,weight[i]
表示第 i
个物品的重量,value[i]
表示第 i
个物品的价值。
物品\容量 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|---|
无物品 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
物品1 | 0 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
物品1,2 | 0 | 2 | 2 | 5 | 7 | 7 | 7 | 7 | 7 |
物品1,2,3 | 0 | 2 | 2 | 5 | 7 | 7 | 8 | 10 | 10 |
2. 一维DP优化
在上述二维DP解法中,我们可以观察到在计算 dp[i][j]
时,只依赖于 dp[i-1][j]
和 dp[i-1][j-weight[i]]
,即只依赖于上一行的结果。因此,我们可以将二维数组优化为一维数组,仅保留一行的信息。
状态转移方程为:
dp[j] = Math.max(dp[j], dp[j - weights[i]] + values[i]);
//相当于直接在二维数组的上一层倒序更新,看看这个容量的背包是保持当前的值最大 还是加入物品后的价值更大
- 二维DP解法的时间复杂度:O(n * capacity),其中 n 是物品的数量,capacity 是背包的容量。空间复杂度为 O(n * capacity)。
- 一维DP优化后的时间复杂度:O(n * capacity),空间复杂度为== O(capacity)==。
通过将二维数组优化为一维数组,我们降低了空间复杂度。
3. 步骤演示
物品 | 背包容量 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---|---|---|---|---|---|---|---|---|---|---|
初始 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
物品1:
- 当背包容量为0时,无法放入物品1,保持为0。
- 当背包容量为8时,放入物品1,dp[8] = 2。
- 当背包容量为7时,放