Expm 6_2 单副本的背包问题
设k[w][j]=基于背包容量w和物品1,...,j所能得到的最高价值
如何将k[w][j]用更小的子问题表示呢?很简单,要么需要选择物品j以获得最高价值,要么不需要:
k[w][j]=max{k[w][j-1],k[w-weight[j]][j-1]+values[j]}
1 public class Exp6_2 { 2 //单副本的背包问题 3 public static void main(String[] args) { 4 int[] weight=new int[]{0,6,3,4,2}; //物品重量1~n 5 int[] values=new int[]{0,30,14,16,9}; //物品价值1~n 6 int maxWeight=10; 7 maxValues(weight,values,maxWeight); 8 /* 9 能放入背包的最大价值为: 46 10 已放入物品:3 11 已放入物品:1 12 */ 13 } 14 /* 15 * weight:物品所对应的重量 16 * values:物品所对应的价值 17 * maxWeight:背包能放入的最大重量 18 */ 19 public static void maxValues(int[] weight,int[] values,int maxWeight){ 20 int count=weight.length; //物品的数量-1 21 int[][] k=new int[maxWeight+1][count]; //容量为w的背包的物品1..j所能得到的最大价值 22 23 for(int i=0;i<count;i++) 24 k[0][i]=0; 25 for(int j=0;j<=maxWeight;j++) 26 k[j][0]=0; 27 28 //容量为w的背包的物品1..j所能得到的最大价值 29 for(int w=1;w<=maxWeight;w++){ 30 for(int j=1;j<=count-1;j++){ 31 if(weight[j]>w) 32 k[w][j]=k[w][j-1]; //物品j不能放入背包,j的重量大于背包的最大承重量 33 else{ 34 //比较放入j与不放入j哪种情况获得更大的价值 35 if(k[w][j-1]>(k[w-weight[j]][j-1]+values[j])) //物品j不放入背包 36 k[w][j]=k[w][j-1]; 37 else{ 38 k[w][j]=k[w-weight[j]][j-1]+values[j]; //物品j放入背包 39 } 40 } 41 } 42 } 43 System.out.println("能放入背包的最大价值为: "+k[maxWeight][count-1]); 44 findObject(maxWeight,count-1,maxWeight,weight,k); 45 } 46 47 public static void findObject(int w,int j,int maxWeight,int[] weight,int[][] k){ 48 if(j>0){ 49 if(k[w][j]==k[w][j-1]) //没放入背包 50 findObject(w,j-1,maxWeight,weight,k); 51 else //已放入背包 52 { 53 System.out.println("已放入物品:"+j); 54 //在物品1..j-1中寻找已放入容量为w-weight[j]的背包的物品 55 findObject(w-weight[j],j-1,maxWeight,weight,k); 56 } 57 } 58 } 59 }

浙公网安备 33010602011771号