完全背包
问题描述
有N件物品,每件物品的重量为weight[ i ],价值为value[ i ]。现有一个容量为W的背包,问如何选取物品放入背包,使得背包内物品的总价值最大。同一物品可以放无限次。
分析
完全背包和01背包还是很像的,唯一不一样的就是同一物品可以无限取多次
先给出状态转移方程:
sum[ i ][ j ]=max(f[ i-1 ][ j - k * weight[ i ] ]+k*value[ i ]),其中0<=k<=V/weight[ i ]
如果不理解可以看看01背包
代码
public class BackPack02 {
//完全背包
static int N=6;//物品有五件
static int W=21;//背包容量为20
static int weight[]= {0,2,3,4,5,9};//重量 2 3 4 5 9
static int value[]= {0,3,4,5,8,10};//价值3 4 5 8 10
public static void getValue() {
int sum[]= new int[W];
for(int i=1;i<N;i++) {
for(int j=1;j<W;j++) {
if(weight[i]<=j) {
sum[j]=Math.max(sum[j], sum[j-weight[i]]+value[i]);
}
}
}
System.out.println(sum[20]);
}
public static void main(String[] args) {
getValue();
}
}
输出
32
问题:为什么只要把 j 遍历顺序改一下就可以了?
01背包的 j 从W-1开始遍历是为了保证每个物品只添加一次,这里 j 从1开始遍历刚好可以保证物品可添加无限次,不信你可以按我在01背包里分析的方法去试一下
优化
对weight数组和value数组遍历,去除价值低而且重的物品,意义不是很大