1.v 是一个长度为 n 的列表,表示每个物品的价值。 4 _5 g4 o- l& S" p. m2 j( l( \2.w 是一个长度为 n 的列表,表示每个物品的重量。 . D. u& M: y' I: P3.n 表示物品的数量。 0 P/ U' x: Y+ K: _4.capacity 表示背包的容量。 & @0 Q: x6 ^/ P0 g5 t* L- g, M9 z- ^' E& _- u) Q( I
代码首先初始化了一个二维数组 m 作为动态规划表,其中 m[j] 表示在考虑前 i 个物品时,背包容量为 j 时可以获得的最大总价值。数组 x 用来存储最终的解,x 表示是否选择第 i 个物品。
for i in range(n): . @* i( t3 ^% ~
for j in range(capacity): |) o3 P: Z\" [& r3 F% b
if (j >= w[i]):! W% W% G7 M0 |9 `5 v; Q g
m[i][j] = max(m[i - 1][j], m[i - 1][j - w[i]] + v[i]) ( E4 f% H9 ?4 R- B. X
else:7 E/ I1 I% O) N6 C* h6 F$ a
m[i][j] = m[i - 1][j]
复制代码
在这个部分,代码使用了一个嵌套的循环,遍历了所有物品和不同的背包容量。对于每个物品 i 和容量 j,代码计算了两种情况下的最大总价值:1 U; R/ Z1 \* Z4 C, y% o5 f
5.如果当前物品的重量 w 小于等于当前容量 j,那么可以选择将第 i 个物品放入背包,此时总价值为 m[i-1][j-w] + v,或者选择不放入,此时总价值为 m[i-1][j]。代码选择其中较大的值作为 m[j]。# K h. d" A" D# Q- L
6.如果当前物品的重量 w 大于当前容量 j,则无法放入物品,所以总价值等于上一行的值 m[i-1][j]。 + H. }0 {4 c1 X9 L4 }& y, r. l8 o& z1 O- F# N) O9 s1 K
这个循环填充了动态规划表 m,最终 m[n-1][capacity] 包含了问题的最优解,即在给定容量下可以获得的最大总价值。
capacity = capacity - 1 # i% U. C. U0 p! Q1 T1 H
for i in range(n - 1, 0, -1): : \, f& o, X4 S' x9 v
if (m[i][capacity] == m[i - 1][capacity]): ) e+ W4 {; s5 z; M# `( F+ f, c. R
x[i] = 0 : j9 V\" ^\" I, n0 ?0 |, X$ d7 k8 [
else: * `2 @, U9 {+ v1 ?5 Z; b; t
x[i] = 1 $ ?3 c) _; u5 T5 j
capacity -= w[i] ! w2 t9 j! I0 }% m+ x& z. g
x[0] = 1 if (m[1][capacity] > 0) else 0
复制代码
在这一部分,代码反向遍历动态规划表,从最后一行向前找到解的路径。如果 m[capacity] 等于 m[i-1][capacity],表示第 i 个物品没有放入背包,否则放入背包,并更新剩余容量 capacity。
weight = 0 3 W% e, f\" w* [+ @
value = 09 ?/ Z' `7 `4 W5 Z) h
print('装载的物品编号为:')+ b r, n% Q, T
for i in range(len(x)): \" Q, R; h$ ^. r- T
if (x[i] == 1):4 m\" M- U: U! j
weight = weight + w[i]5 ?+ B) Z1 M6 B( ~& o$ g
value = value + v[i]. |\" m0 F7 }. A. N5 w% F* x
print(' ', i + 1)* E( N8 y# n/ U& V5 _5 }8 O* n Z\" Z