您的位置:首页 > 其它

01背包问题和完全背包问题

2015-07-02 16:22 281 查看
叙述一下:

01背包问题:

有N件物品和一个容量为V 的背包。放入第i件物品耗费的空间是Ci,得到的价值是Wi。求解将哪些物品装入背包可使价值总和最大。

完全背包问题:

有N种物品和一个容量为V 的背包,每种物品都有无限件可用。放入第i种物品的耗费的空间是Ci,得到的价值是Wi。求解:将哪些物品装入背包,可使这些物品的耗费的空间总和不超过背包容量,且价值总和最大。

先放代码:

01背包问题:

for i 1..n   
  for v V..c[i]       
     f[v]=max{f[v],f[v-c[i]]+w[i]}


完全背包问题:

for i 1..n   
  for v c[i]..V       
     f[v]=max{f[v],f[v-c[i]]+w[i]}


解释一下:

这两段程序的不同之处在于v的枚举顺序。当然,如果不优化为一维,两种顺序都是可以的。但是:

01背包问题:

对于01背包问题,原转移方程实际上是

—–F[i,v] = max { F[i-1,v],F[i-1,v-c[i]]+w[i] }

优化空间后成为

—–F[v] = max { F[v],F[v-c[i]]+w[i] }

这就要求右面的F[v-c[i]]对应的是原F[i-1,v-c[i]],那就需要当计算F[v]时,F[v-c[i]]不能被计算过,仅在此时与c[i]用或不用,这就保证了c[i]最多只是用了一次。从后往前枚举v,v必然在v-c[i]之前出现,因此F[v-c[i]]是原来的值。

完全背包问题:

对于01背包问题,原转移方程实际上是

—–F[i, v] = max { F[i-1, v],F[i,v-c[i]]+w[i] }

与上面不同的是,这里右边的后一项是F[i,v-c[i]],这是因为只有这样,才能使F[i,v]成为有可能包含多次选择某一物品的状态。

优化空间后成为

—–F[v] = max { F[v],F[v-c[i]]+w[i] }

出于上面的要求,我们需要F[v-c[i]]的值有更新,所以需要从前往后枚举v,这样v-c[i]会比v更先得以计算,这样便满足了我们的要求。

实际上,程序中的F[ ]使用是一个滚动数组的运用,F[ ]的值会随循环而不断更新,因此可以通过调整v的枚举顺序去改变更新顺序,从而对01背包和完全背包的要求进行实现。

推荐参考的文章(01背包、完全背包、多重背包)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: