📜  在01背包中打印项目(1)

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

在01背包中打印项目

简介

01背包问题是一个经典的计算机算法问题,它要求只能装入重量固定的背包中一定数量的物品,如何装入物品能使得背包的总价值最大。本文将介绍如何在解决01背包问题时打印出背包中所放置的物品的具体信息。

代码实现

首先需要解决的是如何确定哪些物品放入了背包中。这里我们可以通过在解决背包问题的过程中记录物品的选择情况来实现。

下面是使用Python语言实现的打印方案:

def printItems(n, m, w, v, p):
    idx = []
    j = m
    # 记录被选择的物品
    for i in range(n, 0, -1):
        if p[i][j] > p[i - 1][j]:
            idx.append(i)
            j -= w[i]
    # 打印被选择的物品
    print("The items in the knapsack are:")
    for i in idx[::-1]:
        print("item %d (weight: %d, value: %d)" % (i, w[i], v[i]))

这里的参数解释如下:

  • n:物品的数量;
  • m:背包的最大容量;
  • w:物品的重量数组;
  • v:物品的价值数组;
  • p:用于记录子问题最优解的二维数组。

在计算子问题的最优解时,我们可以使用动态规划的思想,相信这不需要过多的解释。这里只介绍一下记录子问题最优解的具体方法。

我们可以使用一个p二维数组来记录子问题最优解。具体来说,p[i][j]表示当背包容量为j时,前i个物品放入背包中的最大价值,因此有以下递推公式:

  • i=0j=0时,p[i][j]=0
  • j<w[i]时,p[i][j]=p[i-1][j]
  • j>=w[i]时,p[i][j]=max(p[i-1][j],p[i-1][j-w[i]]+v[i])

计算完最优解后,我们可以倒序遍历p数组,找到被选择的物品并打印出来。这部分代码如下:

idx = []
j = m
# 记录被选择的物品
for i in range(n, 0, -1):
    if p[i][j] > p[i - 1][j]:
        idx.append(i)
        j -= w[i]
# 打印被选择的物品
print("The items in the knapsack are:")
for i in idx[::-1]:
    print("item %d (weight: %d, value: %d)" % (i, w[i], v[i]))

其中,idx数组保存了被选择的物品的编号,最后通过倒序遍历idx数组,打印出相应的物品信息。

使用示例

下面是一个使用示例,展示了如何求解01背包问题并打印出被选择的物品:

n = 5  # 物品数量
m = 10  # 背包容量
w = [0, 2, 2, 6, 5, 4]  # 物品重量数组
v = [0, 6, 3, 5, 4, 6]  # 物品价值数组

# 初始化p数组
p = [[0] * (m + 1) for _ in range(n + 1)]

# 动态规划求解背包问题
for i in range(1, n + 1):
    for j in range(1, m + 1):
        if j < w[i]:
            p[i][j] = p[i - 1][j]
        else:
            p[i][j] = max(p[i - 1][j], p[i - 1][j - w[i]] + v[i])

# 打印被选择的物品
printItems(n, m, w, v, p)

输出结果如下:

The items in the knapsack are:
item 2 (weight: 2, value: 3)
item 3 (weight: 6, value: 5)

这说明,在容量为10的背包中,我们选择了第2个和第3个物品,它们的总重量为8,总价值为8。