数据结构与算法之 leetcode 动态规划背包 0 1 / 完全 / 多重背包

数据结构与算法阿木 发布于 6 天前 3 次阅读


摘要:

动态规划背包问题是计算机科学中一个经典的问题,它涉及到如何在一个有限的空间内,以最优的方式放置物品。本文将围绕0-1背包、完全背包和多重背包问题,通过代码实现和理论分析,深入探讨动态规划在解决背包问题中的应用。

一、

背包问题是一个经典的优化问题,它起源于现实生活中的物品装载问题。在背包问题中,给定一组物品,每个物品都有一定的价值和重量,我们需要选择一个子集,使得这些物品的总价值最大,同时不超过背包的容量限制。根据物品数量的不同,背包问题可以分为0-1背包、完全背包和多重背包问题。

二、0-1背包问题

0-1背包问题是最基本的背包问题,它要求每个物品只能选择一次或者不选择。下面是0-1背包问题的代码实现:

python

def knapsack_01(values, weights, capacity):


n = len(values)


dp = [[0] (capacity + 1) for _ in range(n + 1)]

for i in range(1, n + 1):


for w in range(1, capacity + 1):


if weights[i - 1] <= w:


dp[i][w] = max(dp[i - 1][w], dp[i - 1][w - weights[i - 1]] + values[i - 1])


else:


dp[i][w] = dp[i - 1][w]

return dp[n][capacity]

示例


values = [60, 100, 120]


weights = [10, 20, 30]


capacity = 50


print(knapsack_01(values, weights, capacity))


三、完全背包问题

完全背包问题与0-1背包问题类似,但每个物品可以无限次选择。以下是完全背包问题的代码实现:

python

def knapsack_full(values, weights, capacity):


n = len(values)


dp = [0] (capacity + 1)

for i in range(n):


for w in range(weights[i], capacity + 1):


dp[w] = max(dp[w], dp[w - weights[i]] + values[i])

return dp[capacity]

示例


values = [60, 100, 120]


weights = [10, 20, 30]


capacity = 50


print(knapsack_full(values, weights, capacity))


四、多重背包问题

多重背包问题是对完全背包问题的扩展,它允许每个物品有多个,但数量有限。以下是多重背包问题的代码实现:

python

def knapsack_multiple(values, weights, capacities, capacity):


n = len(values)


dp = [0] (capacity + 1)

for i in range(n):


for w in range(1, capacities[i] + 1):


for j in range(w, capacity + 1):


dp[j] = max(dp[j], dp[j - w weights[i]] + w values[i])

return dp[capacity]

示例


values = [60, 100, 120]


weights = [10, 20, 30]


capacities = [2, 3, 1]


capacity = 50


print(knapsack_multiple(values, weights, capacities, capacity))


五、总结

本文通过代码实现和理论分析,详细介绍了0-1背包、完全背包和多重背包问题。动态规划是一种有效的解决背包问题的方法,它通过将问题分解为更小的子问题,并存储子问题的解来避免重复计算。在实际应用中,根据问题的具体要求选择合适的背包模型,可以有效地解决物品装载问题。

六、扩展阅读

- 动态规划算法原理与实例分析

- 背包问题的变体与应用

- 动态规划在计算机科学中的应用

通过本文的学习,读者可以更好地理解动态规划背包问题的解决方法,并在实际项目中应用这些知识。