背包的变化 - 精确重量的最小总成本

时间:2013-03-18 12:08:19

标签: algorithm dynamic-programming knapsack-problem

有各种类型的物品(N种类型),每种都有重量wi和成本ci。每个都有无穷无尽的数量。问题是制作具有EXACT(W)重量和最小物品总成本的背包。我知道在这种情况下我应该使用动态,但这不是通常的背包问题,我找不到关系。我也发现了一些类似的问题,但我还没有理解这些问题。以下是12的链接。 如何使用DP来解决它?

2 个答案:

答案 0 :(得分:4)

让f [i]表示,为了获得权重i,最低成本。 g [i]表示是否可以精确组合权重i;

f[0]=0;g[0]=true;
for (int i=0;i<N;i++)
    for (int j=0;j<W;j++)
        if (g[j]) {
            g[j+w[i]]=true;
            if (f[j+w[i]]==0||f[j+w[i]]>f[j]+c[i])
                f[j+w[i]]=f[j]+c[i];
        }

if (g[W]) return f[W];
else return 0;//impossible

答案 1 :(得分:2)

假设您想要找到最低费用,可以用来完成W以及c_i > 0w_i > 0的权重,然后我们可以将min_cost(i, W)定义为最低仅使用权重为i的{​​{1}}到N的项目可以实现的费用

  • 基本案例发生在我们只有一个项目时,因此W时。在这种情况下,解决方案是:

    i=N因为如果我们不使用项目min_cost(N, 0) = 0,那么我们的权重已经等于0

    N如果min_cost(N, W) = c_i * W / w_iW的倍数,即w_i

    W mod w_i = 0否则,因为我们无法仅使用最后一项获得min_cost(N, W) = Infinity的权重。

  • 现在可以将经常性关系表述为:

    直到W

  • min_cost(i, W) = min(c_i * k + min_cost(i+1, W - k * w_i))

    k=0

经常性关系表明,我们将尽可能多地使用项目W - k*w_i < 0,而我们的权重未超过i

然后,您可以使用memoization的递归算法实现此方法,并根据需要存储实际解决方案(重复中的W)。

修改根据建议,如果我们发现有两种情况会影响k,则可以实现加速。这种情况首先是不需要首先使用第i个项目min_cost(i, W),当我们要使用第i个项目至少一次时,这与min_cost(i+1, W)相同,因为我们可能会使用项目min_cost(i, W - w_i)不止一次。这会将我们的重现更改为以下内容:

i