在一个背包的情况下,最佳地填充背包的动态编程算法很有效。但是,是否有一种有效的已知算法可以最佳地填充2个背包(容量可能不相等)?
我尝试了以下两种方法,但两种方法都不正确。
问题陈述(另见维基百科的Knapsack Problem):
我们必须用一组物品填充背包(每个物品都有一个重量和一个值),以便最大化我们从物品中获得的价值,同时总重量小于或等于背包尺码。
我们不能多次使用一个项目。
答案 0 :(得分:11)
我会假设每个n
项目只能使用一次,您必须最大化您的利润。
原始背包是dp[i] = best profit you can obtain for weight i
for i = 1 to n do
for w = maxW down to a[i].weight do
if dp[w] < dp[w - a[i].weight] + a[i].gain
dp[w] = dp[w - a[i].weight] + a[i].gain
现在,由于我们有两个背包,我们可以使用dp[i, j] = best profit you can obtain for weight i in knapsack 1 and j in knapsack 2
for i = 1 to n do
for w1 = maxW1 down to a[i].weight do
for w2 = maxW2 down to a[i].weight do
dp[w1, w2] = max
{
dp[w1, w2], <- we already have the best choice for this pair
dp[w1 - a[i].weight, w2] + a[i].gain <- put in knapsack 1
dp[w1, w2 - a[i].weight] + a[i].gain <- put in knapsack 2
}
时间复杂度为O(n * maxW1 * maxW2)
,其中maxW
是背包可以携带的最大重量。请注意,如果容量很大,则效率不高。
答案 1 :(得分:1)
原始DP假设您在dp数组中标记了您可以在背包中获得的值,并且通过考虑元素来完成更新。
在2个背包的情况下你可以使用2维动态阵列,所以 dp [i] [j] = 1 当你可以把重量 i 放在第一位且重量 j 到第二个背包。更新类似于原始DP案例。
答案 2 :(得分:1)
递归公式是任何人都在寻找:
给定n个项目,使得项目i具有权重wi和值pi。这两个背包具有W1和W2的容量。
对于每0 <= i <= n,0 <= a <= W1,0 <= b <= W2,表示M [i,a,b]为最大值。
对于&lt; 0或b&lt; 0-M [i,a,b] =-∞ 对于i = 0,或a,b = 0-M [i,a,b] = 0
公式: M [i,a,b] = max {M [i-1,a,b],M [i-1,a-wi,b] + pi,M [i-1,a,b-wi] + PI}
i项目问题的每个解决方案都有背包1中的项目i,背包2或其中没有任何项目。