1.问题
已知现有物品m件(物品0,1,2,3,...m-1),背包的最大承重为n,计算把这个m件物品放到这个背包中可取得的最大价值。
针对每个物品存有其名称、重量和价值。
/**
* 表示每个物品的类。
*/
class BagItem{
String name;//物品的名字
int weight;//物品的重量
int value;//物品的价值
public BagItem(String name,int weight,int value){
this.name = name;
this.weight = weight;
this.value = value;
}
}
2.采用动态规划的思想做这个题目
物理意义上用f[i][j]中存的是前i个物品放到最大承重为j的背包中可取得的最大重量。
决策方式:第i件物品是否放进去取决于放进去第i件物品得到的价值f[i-1][j-B[i].weight]+B[i].value(j>=B[i].weight) 和不放进去第i件物品时的价值f[i-1][j]比较结果.
s[i][j]表示在f[i][j]取得最大值时背包内的各个物品名称。
这样最后求的java数组中f[m-1][n]即为最大承重为n的背包中可放的那m件物品的最大重量。s[m-1][n]即为最后结果。
/**
* 解决0-1背包问题
* 动态规划.
* 物理意义上f[i][j]中存的是前i个物品放到最大承重为j的背包中可取得的最大重量。
* 第i件物品是否放进去取决于
* 放进去第i件物品得到的价值f[i-1][j-B[i].weight]+B[i].value(j>=B[i].weight) 和不放进去第i件物品时的价值f[i-1][j]比较结果.
* s[i][j]表示在f[i][j]取得最大值时背包内的各个物品名称。
*
*/
public class Bag01 {
public int[][] f;
public String[][] s;
int m;//物品总数
int n;//背包的最大承重
public Bag01(int m,int n){
this.m = m;
this.n = n;
f = new int[m][n];
s = new String[m][n];
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
s[i][j] = "";
}
}
}
public void selectBigValue(BagItem[] B){
/*初始化代码第0件物品的操作操作*/
for(int j=0;j<n;j++){
if(j>=B[0].weight){
f[0][j] = B[0].value;
s[0][j] = B[0].name;
}
}
/*按照决策公式决定下一件物品是否要放到背包中*/
for(int i=1;i<m;i++){
for(int j=0;j<n;j++){
if(j>=B[i].weight && f[i-1][j-B[i].weight]+B[i].value > f[i-1][j] ){
f[i][j] = f[i-1][j-B[i].weight] + B[i].value;
s[i][j] = s[i-1][j-B[i].weight] + B[i].name;
}else{
f[i][j] = f[i-1][j];
s[i][j] = s[i-1][j];
}
}
}
}
}
在调用的时候需要注意:
如当背包的最大承重是10时,初始化矩阵为11行,j才可以取到10。
public static void main(String[] args){
BagItem[] B = new BagItem[5];
B[0] = new BagItem("f",2,6);
B[1] = new BagItem("c",4,6);
B[2] = new BagItem("d",5,4);
B[3] = new BagItem("e",6,5);
B[4] = new BagItem("b",2,3);
/*注意:当背包的最大承重是10时,初始化矩阵为11行,j才可以取到10*/
Bag01 test = new Bag01(5,10);
test.selectBigValue(B);
/*输出背包内的价值矩阵*/
for(int i=0;i<test.m;i++){
for(int j=0;j<test.n;j++){
System.out.print(test.f[i][j]+" ");
}
System.out.println();
}
/*输出对应f[i][j]取得最大值时背包内的物品名称。*/
for(int i=0;i<test.m;i++){
for(int j=0;j<test.n;j++){
System.out.print(test.s[i][j]+" ");
}
System.out.println();
}
}
代码的执行结果如下