完全背包

来源:互联网 发布:魔方还原软件 编辑:程序博客网 时间:2024/04/27 16:01

题目:有一个最大载重为W的背包,有n中物品,第i件物品的价值为value[i],重量为weight[i],其中每件物品的数量有限,第i件物品最多有num[i]件,求背包最多可以装载物品的价值之和。

  对比01背包的问题,完全背包和它的不同之处在于第i件物品的数量变为num[i],而不是1件。我们不难想出把相同的物品看做不同的物品,转化后的物品只有1件,那么问题就变成了有num[1]+num[2]+…+num[n]件物品的01背包问题。
  但是,用这种算法我们能够感受到它的效率低,它的时间复杂度为O(Wni=1num[i]),因为有个信息我们没有用到,那就是有相同种类的物品,它的数量num[i],这意味这有num[i]件物品是相同的,而我们上面的算法却是把他们当做不同的物品看待。所以,为了利用这一信息,我们需要优化一下算法。
  我们首先得回顾一下正整数的表达方式。我们知道任意一个正整数可以用二进制的方式表示,比如6在二进制的形式下即为 110,因为6=1*2^2+1*2^1+0*2^0。
  那么我们假如现在有个物品有6件,单件物品的价值为2,重量为3,当我们把它转换成01背包问题时我们可以把该物品扩充为3种物品,每种物品只有一件:
  第一种为物品A,价值为2,重量为3;
  第二种为物品B,价值为4,重量为6;
  第三种为物品C,价值为8,重量为12;

我们现在只需要证明对于小于或等于6的数都可以用A/B/C的组合表示出来,而且ABC的系数只能为1或0。这和上面二进制表示数的问题是一样的,所以这个命题是正确的。

再回到原题,如果我们把物品分割成多重其他物品,那么就成功把算法的时间复杂度降为O(Wni=1log(num[i])),面对大量数据时,这是一个极大的提升。

0 0
原创粉丝点击