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 }
View Code

 

posted @ 2017-11-01 19:23  清风☆薰衣草  阅读(292)  评论(0)    收藏  举报