返回

01背包问题-动态规划

前端

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背包问题的动态规划算法步骤:

  1. 初始化动态规划表
for i = 0 to n
    dp[i][0] = 0
  1. 计算动态规划表
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])
  1. 回溯得到最优解
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)的特点。