01背包问题详解
问题描述
给定一个背包,其容量为 $C$,现在有 $n$ 个物品,其中第 $i$ 个物品的体积为 $w_i$,价值为 $v_i$。问如何选择物品放入背包中,使得背包中物品的总价值最大。
思路分析
动态规划
这是一个经典的动态规划问题,可以使用动态规划来解决。我们定义 $dp[i][j]$ 表示前 $i$ 个物品中,容量为 $j$ 的背包可获得的最大价值,根据0/1选择性,我们可以得到如下状态转移方程:
$$
\begin{aligned}
dp[i][j] &=\begin{cases}
0, & i=0 \text{or} j=0 \
dp[i-1][j], & j<w_i \
\max(dp[i-1][j],dp[i-1][j-w_i]+v_i), & j \geqslant w_i
\end{cases}
\end{aligned}
$$
最终的答案为:$dp[n][C]$
代码实现
def knapsack(n, C, w, v):
dp = [[0 for j in range(C+1)] for i in range(n+1)]
for i in range(1, n+1):
for j in range(1, C+1):
if j < w[i-1]:
dp[i][j] = dp[i-1][j]
else:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i-1]]+v[i-1])
return dp[n][C]
示例说明
示例一
假如有一个包,它最多只能容纳重量和体积为 $10$ 千克的物品,以下是 $5$ 个物品及它们的重量和其对应的价值。现在希望找到最佳的打包方法使得总价值最大化。
物品 | 重量 | 价值 |
---|---|---|
A | 2 | 6 |
B | 2 | 2 |
C | 3 | 8 |
D | 4 | 9 |
E | 5 | 7 |
n = 5
C = 10
w = [2, 2, 3, 4, 5]
v = [6, 2, 8, 9, 7]
print(knapsack(n, C, w, v)) # 输出为:20
示例二
我们现在有 $4$ 个物品,其重量和价值分别为:
物品 | 重量 | 价值 |
---|---|---|
A | 2 | 2 |
B | 3 | 4 |
C | 4 | 5 |
D | 5 | 8 |
我们现在有 $10$ 的背包容量。
n = 4
C = 10
w = [2, 3, 4, 5]
v = [2, 4, 5, 8]
print(knapsack(n, C, w, v)) # 输出为:15
在这个示例中,最优的选择方式是选择物品 A、B、C,它们的重量和为 $9$,总价值为 $11$。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详解01背包问题原理与使用方法 - Python技术站