题目:
有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
基本思路:
方法有三种:
-
直接转换为O-1背包问题
-
虽然物品数量不限,但由于背包容量有限,故物品能装入的最大数量也受到限制,第i种物品最多可以装入n[i] = V/c[i]个,这样就有了两种思路,一是把第i种物品划分为n[i]个等费用等价值的独立物品,然后采用0-1背包的方程即可:
f[i][v] = max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
二是增加一个变量k对第i种物品加入的数量进行计数:
f[i][v] = max{f[i-1][v],f[i-1][v-k*c[i]]+k*w[i]}
- 采用二进制思想有限的组合物品
1、2、5分可以组合任意钱数x,那么把c[i]划分为只适合于自己的k个子集合,就可以大大减少物品数,从而在物品数量上对第一种方法进行优化。
策略:分成c[i]*2^(k-1)的物品,条件为c[i]*2^(k-1)<=V,外加c[i]*(n[i]-omi(k)),如13可以划分为1,2,4,6
方程是不变的,只是物品数量少了。
- 直接解
由于选择有后效性,故方程为:
f[i][v] = max{f[i-1][v],f[i][v-c[i]]+w[i]}
- 大师级无敌O(VN)方法
for i = 1..N
for v = 0..V
f[v] = max{f[v],f[v-cost]+weight}
由于方法太过巧妙,至今我都没有想明白,正在深入研究。 由直接解的方法一维数组实现得到。