返回
01背包问题-动态规划
前端
2023-09-14 14:07:32
01背包问题是一个经典的动态规划问题,它了一个背包只能装入特定重量的物品,如何选择装入背包的物品,才能使背包中物品的总价值最大。
要解决01背包问题,我们需要定义一个动态规划表dp,其中dp[i][j]表示前i个物品放入容量为j的背包中所能获得的最大价值。
dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])
其中,w[i]和v[i]分别表示第i个物品的重量和价值。
以下是01背包问题的动态规划算法步骤:
- 初始化动态规划表
for i = 0 to n
dp[i][0] = 0
- 计算动态规划表
for i = 1 to n
for j = 1 to W
dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])
- 回溯得到最优解
x = n
y = W
while x > 0 and y > 0
if dp[x][y] != dp[x-1][y]
selected.add(x)
y = y - w[x]
x = x - 1
以下是01背包问题的动态规划算法示例代码:
def knapsack(items, W):
"""
求解01背包问题
参数:
items: 物品列表,每个物品由重量和价值组成
W: 背包容量
返回:
背包中物品的最大总价值
"""
# 初始化动态规划表
dp = [[0 for _ in range(W + 1)] for _ in range(len(items) + 1)]
# 计算动态规划表
for i in range(1, len(items) + 1):
for j in range(1, W + 1):
if items[i - 1][0] <= j:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-items[i - 1][0]] + items[i - 1][1])
else:
dp[i][j] = dp[i-1][j]
# 回溯得到最优解
x = len(items)
y = W
selected = []
while x > 0 and y > 0:
if dp[x][y] != dp[x-1][y]:
selected.append(items[x - 1])
y = y - items[x - 1][0]
x = x - 1
# 返回背包中物品的最大总价值
return dp[len(items)][W], selected
# 测试代码
items = [(3, 4), (4, 5), (2, 3), (5, 6)]
W = 10
print(knapsack(items, W))
算法复杂度
01背包问题的动态规划算法的时间复杂度为O(nW),其中n为物品的数量,W为背包的容量。空间复杂度为O(nW)。
总结
01背包问题是动态规划问题中的一个典型例子。它是一种经典的算法设计范式,可以用来解决许多其他问题。01背包问题的动态规划算法具有时间复杂度为O(nW)和空间复杂度为O(nW)的特点。