三、背包问题
给定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