返回

多重背包:完全背包的进阶之旅

后端

引子

在算法和数据结构的王国中,背包问题是一个备受推崇的经典。它了一个背包容量有限的问题,在这个背包中,我们必须挑选物品来填充,而每种物品都有自己的价值和重量。背包问题衍生出了多种变体,其中完全背包和多重背包颇具代表性。

完全背包与多重背包

完全背包是一种背包问题,它允许每种物品在背包中出现任意多次。相比之下,多重背包则对每种物品的出现次数提出了限制。在多重背包问题中,每种物品都有一个特定的数量,我们只能在背包中放置不超过该数量的物品。

转化思路

有趣的是,我们可以通过限制背包容量的技巧,将完全背包问题转化为多重背包问题。具体来说,我们将完全背包的容量设置为每个物品数量的总和。这样一来,每种物品就只能在背包中出现一次,从而满足了多重背包的限制。

状态转移方程

对于完全背包问题,其状态转移方程为:

dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])

其中,dp[i][j] 表示考虑前 i 个物品时,背包容量为 j 时背包中的最大价值,w[i] 和 v[i] 分别表示第 i 个物品的重量和价值。

将完全背包转化为多重背包后,状态转移方程变为:

dp[i][j] = max(dp[i-1][j], dp[i][j-w[i]] + v[i])

其中,背包的容量 j 已经限定为每个物品数量的总和,因此不再作为参数出现。

示例

假设我们有 3 种物品,每种物品的数量如下:

物品 数量
A 2
B 3
C 1

背包容量为 6。

完全背包:

背包容量 0 1 2 3 4 5 6
考虑物品 0 0 0 0 0 0 0
物品 A 0 6 12 18 24 30 36
物品 B 0 6 12 18 24 30 36
物品 C 0 6 12 18 24 30 36

多重背包:

背包容量 0 1 2 3 4 5 6
考虑物品 0 0 0 0 0 0 0
物品 A 0 6 12 18 18 18 18
物品 B 0 6 12 18 18 18 18
物品 C 0 6 12 18 18 18 18

可以看出,通过将完全背包的容量限制为每个物品数量的总和,我们得到了与多重背包相同的结果。

结语

完全背包向多重背包的转化是一个妙趣横生的算法技巧,它揭示了不同背包问题之间的微妙联系。通过巧妙地修改背包容量,我们可以将复杂的多重背包问题简化为更加熟悉的完全背包问题,从而简化了求解过程。这一转化不仅拓宽了我们的算法视野,也为我们解决更复杂的问题提供了新的思路。