三、背包问题
给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包的物品,使得装入背包中物品的总价值最大?
思路请参考:
https://blog.csdn.net/dapengbusi/article/details/7463968
代码:
package dataStructureAndAlgorithms;
public class KnapsackProblem {
public static int getMaxValue(int[] w, int[] v,int[][] maxValue, int capacity) {
int commodityNumber = w.length - 1;
//[从0开始可以选择的商品范围][背包容量]
//没有商品可选时,不论包容量多大都为0
for(int i=0;i<=capacity;i++){
maxValue[0][i] = 0;
}
//确定是否选择第i件商品
for(int i=1;i<=commodityNumber;i++){
//当背包容量小于w[i]时
for(int j=0;j<w[i];j++){
maxValue[i][j] = maxValue[i-1][j];
}
//分别求出选择此商品和不选择此商品时的最大值
for(int j=w[i];j<=capacity;j++){
int choose = maxValue[i-1][j-w[i]] + v[i];
int notChoose = maxValue[i-1][j];
maxValue[i][j] = choose>notChoose?choose:notChoose;
}
}
return maxValue[commodityNumber][capacity];
}
public static void getChoosedCommodities(int[] w, int[] v, int[][] maxValue, int capacity, boolean[] choosed){
int commodityNumber = w.length - 1;
//分别判断每件商品是否有被选择
for(int i=commodityNumber;i>=1;i--){
//选择了第i件商品
if(maxValue[i][capacity] == maxValue[i-1][capacity-w[i]] + v[i]){
choosed[i] = true;
//子问题对应的容量
capacity = capacity-w[i];
}
}
}
public static void main(String[] args) {
int w[] = { 0, 2, 2, 6, 5, 4 };// 物品的重量 第一个元素0起填充的作用 方便下标处理
int v[] = { 0, 6, 3, 5, 4, 6 };// 物品对应的价值
int capacity = 10;
int[][] maxValue = new int[w.length][capacity+1];
boolean[] choosed = new boolean[w.length];
System.out.println("最大值:"+getMaxValue(w, v, maxValue, 10));
System.out.print("方案:");
getChoosedCommodities(w,v,maxValue,10,choosed);
for(int i=1;i<=w.length-1;i++){
System.out.print(choosed[i] + " ");
}
}
}
结果:
最大值:15
方案:true true false false true