算法与Python

算法与Python 知识量:10 - 40 - 100

8.3 背包问题><

问题- 8.3.1 -

有N个重量为w1,w2,...,wn、价值为v1,v2,...,vn的物品和一个承重量为W的背包,求让背包里装入的物品具有最大的价值总和的物品子集。

问题求解- 8.3.2 -

这是一个经典的0-1背包问题,可以使用动态规划算法求解。以下是Python代码实现:

def knapsack(weights, values, W):  
    n = len(weights)  
    # 初始化动态规划表格dp,dp[i][j]表示在前i个物品中选择,总重量不超过j的情况下,能够得到的最大价值  
    dp = [[0 for _ in range(W + 1)] for _ in range(n + 1)]  
  
    # 动态规划填表  
    for i in range(1, n + 1):  
        for j in range(1, W + 1):  
            if weights[i - 1] <= j:  # 如果第i个物品的重量小于等于当前背包容量  
                dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weights[i - 1]] + values[i - 1])  
            else:  # 如果第i个物品的重量大于当前背包容量,则不能放入背包中  
                dp[i][j] = dp[i - 1][j]  
  
    # 返回最大价值  
    return dp[n][W]  
  
# 示例  
weights = [2, 2, 6, 5, 4]  
values = [6, 3, 5, 4, 6]  
W = 10  
print(knapsack(weights, values, W))  # 输出:20

在这个例子中,有5个物品,它们的重量分别是[2, 2, 6, 5, 4],对应的价值分别是[6, 3, 5, 4, 6]。背包的承重量是10。调用knapsack函数后,返回的结果是20,表示在不超过背包承重量的前提下,可以选择的物品子集的最大价值总和是20。这个子集包括第一个物品(重量2,价值6)和第四个物品(重量4,价值6),以及第五个物品(重量4,价值6),它们的总重量是10,总价值是20。注意这里有多种组合方式可以得到最大价值,动态规划算法给出的是最大价值,但不一定给出具体的物品组合方式。如果需要知道具体的物品组合方式,需要对动态规划算法进行一定的修改。