48 lines
1.3 KiB
Python
48 lines
1.3 KiB
Python
|
|
"""
|
||
|
|
0/1 背包问题 — 动态规划经典问题
|
||
|
|
给定容量 W 和价值/重量数组,求最大价值
|
||
|
|
"""
|
||
|
|
|
||
|
|
def knapsack_01(weights, values, W):
|
||
|
|
"""0/1背包 DP 解法"""
|
||
|
|
n = len(weights)
|
||
|
|
# dp[i][w] 表示前 i 个物品在容量 w 下的最大价值
|
||
|
|
dp = [[0] * (W + 1) for _ in range(n + 1)]
|
||
|
|
|
||
|
|
for i in range(1, n + 1):
|
||
|
|
for w in range(1, W + 1):
|
||
|
|
if weights[i - 1] <= w:
|
||
|
|
# 选或不选当前物品
|
||
|
|
dp[i][w] = max(
|
||
|
|
dp[i - 1][w],
|
||
|
|
dp[i - 1][w - weights[i - 1]] + values[i - 1]
|
||
|
|
)
|
||
|
|
else:
|
||
|
|
dp[i][w] = dp[i - 1][w]
|
||
|
|
|
||
|
|
return dp[n][W]
|
||
|
|
|
||
|
|
def knapsack_01_optimized(weights, values, W):
|
||
|
|
"""空间优化版:一维数组"""
|
||
|
|
dp = [0] * (W + 1)
|
||
|
|
|
||
|
|
for i in range(len(weights)):
|
||
|
|
for w in range(W, weights[i] - 1, -1):
|
||
|
|
dp[w] = max(dp[w], dp[w - weights[i]] + values[i])
|
||
|
|
|
||
|
|
return dp[W]
|
||
|
|
|
||
|
|
if __name__ == "__main__":
|
||
|
|
weights = [2, 3, 4, 5]
|
||
|
|
values = [3, 4, 5, 6]
|
||
|
|
W = 8
|
||
|
|
|
||
|
|
result1 = knapsack_01(weights, values, W)
|
||
|
|
result2 = knapsack_01_optimized(weights, values, W)
|
||
|
|
|
||
|
|
print(f"物品重量: {weights}")
|
||
|
|
print(f"物品价值: {values}")
|
||
|
|
print(f"背包容量: {W}")
|
||
|
|
print(f"最大价值 (二维DP): {result1}")
|
||
|
|
print(f"最大价值 (一维优化): {result2}")
|