解决每个项目具有“最小值”约束的背包概率

时间:2013-03-31 09:26:20

标签: dynamic-programming knapsack-problem

每个项目都有三个属性

  • 项目S i
  • 的大小
  • 项目V i
  • 的值
  • 将项目添加到背包中的最小值M i (< = 10 7

这将是最多100项。

我们给出了背包K(K <= 1000)的大小和初始值V(在背包中没有空间)。
一个项目&#39; i&#39;当且仅当M i 小于或等于V时才能放入背包。
在背包中添加项目后V增加V i
我们必须最大化放入给定尺寸背包的物品数量(而不是价值)。

我发现this question类似。但答案中描述的算法是立方时间,这对于这个问题来说不够快。我们如何以更好的方式解决这个问题?

1 个答案:

答案 0 :(得分:1)

我可以在这里给出一个O(n ^ 3)算法。我不知道这个问题是否可以进一步优化为O(n ^ 2)。

首先,这个问题是如果项目数量最大化,这与其他背包问题有点不同。同时,它还有一个限制,即当背包的总值大于其自身值时,只能选择单个项目。因此,一个明显的推论是,在选择相同数量的项目并确定总大小的情况下,总值应该尽可能大(以便可以将更多项目添加到背包中)。

请注意,项目数n(&lt; = 100)和背包K的大小(&lt; = 1000)不是很大,让f [i] [j]表示选择i项目时的最大值总大小j。最初,除f [0] [0] = V外,所有f [i] [j]都设置为0。

然后根据添加所需的最小值对项目进行排序。这是一种贪婪的想法,因为在排序之后,我们只能查看每个项目一次。

DP方法如下所示:

for (int k=0;k<n;k++) //iterate items
    for (int i=n;i>=0;i--)
        for (int j=K;j>=0;j--) if (item.M[k]<=f[i][j])
            f[i+1][j+item.S[k]]=max(f[i+1][j+item.S[k]],f[i][j]+item.V[k]);

最终答案(最大项目数)是:

for (int i=n;i>=0;i--)
    for (int j=0;j<=K;j++)
        if (f[i][j]) return i;