📜  DAA | 01背包问题(1)

📅  最后修改于: 2023-12-03 15:14:35.384000             🧑  作者: Mango

DAA | 01背包问题

介绍

01背包问题是一种经典的动态规划问题,它的目标是在一定的背包容量下,选择一些物品使得价值最大。动态规划的思想在这个问题中得到了巧妙的应用。

算法

我们先来看一下背包问题的状态转移方程:

  • 如果第i个物品放不进去的情况下:V[i][W]=V[i-1][W]
  • 如果第i个物品放得下的情况下:V[i][W]=max(V[i-1][W-w[i]]+v[i],V[i-1][W])

其中,V[i][W]表示前i个物品中,最大容量为W的背包可以放进去的最大价值,w[i]表示第i个物品的重量,v[i]表示第i个物品的价值。

接下来,我们详细介绍一下算法的实现过程:

def knapsack(W, wt, val, n):

    # 创建一个动态规划数组
    K = [[0 for x in range(W + 1)] for x in range(n + 1)]

    # 填充动态规划数组
    for i in range(n + 1):
        for w in range(W + 1):
            if i == 0 or w == 0:
                K[i][w] = 0
            elif wt[i-1] <= w:
                K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]], K[i-1][w])
            else:
                K[i][w] = K[i-1][w]

    # 返回最大价值和所选的物品
    return K[n][W], [i for i in range(n, 0, -1) if K[i][W] != K[i-1][W]]

该算法的时间复杂度为O(nW),其中n为物品数量,W为背包容量。

示例

下面是一个示例,背包容量为50,给出物品的重量和价值:

wt = [10, 20, 30]
val = [60, 100, 120]
W = 50
n = len(val)
print(knapsack(W, wt, val, n))

输出结果为:

(220, [3, 2])

其中,220为最大价值,[3, 2]为选中的物品编号,表示选择了第3个和第2个物品,它们的重量之和为50,价值之和为220。

结论

通过以上介绍可以看出,动态规划是解决01背包问题的一种非常有效的方法。希望大家可以根据算法的思想,结合实际问题,灵活运用动态规划算法来解决问题。