package chen.Algorithm.dynamic;
public class KnapstackPro {
public static void main(String[] args) {
int[] w = {1,4,3};//物品重量
int[] val = {1500,3000,2000};//物品的价格
int m = 4;//背包容量
int n = val.length;//物品个数
//为了记录放入商品的情况,定义一个二维数组
int[][] path = new int[n+1][m+1];
//创建二维数组
//v[i][j]:表示在容量为j的背包下,前i个物品所能组合的最大价值
int[][] v = new int[n+1][m+1];
//初始化第一行与第一列,在本程序中无意义,不去处理
for (int i = 0; i < v.length; i++) {
v[i][0] = 0;//第一列设置为0
}
for (int i = 0; i < v[0].length; i++) {
v[0][i] = 0;//将第一行设置为0
}
//根据公式动态规划处理
for (int i = 1; i < v.length; i++) {//不处理第一行:商品编号
for (int j = 1; j < v[0].length; j++) {//不处理第一列:当前重量
if(w[i - 1] > j){//由于表示的物品的编号,但是在w数组中,应该是从0开始计算物品,
//这里的i由于特殊性就只能从1开始,因此我们需要减1
v[i][j] = v[i - 1][j];
}else{
//因为我们的i是从1开始的,因此公式需要调整成:
v[i][j] = Math.max(v[i -1][j], val[i-1] +v[i-1][j-w[i-1]]);
//为了记录商品存放到背包的情况,需要使用ifelse体现
if(v[i -1][j] < val[i-1] +v[i-1][j-w[i-1]]){
v[i][j] = val[i-1] +v[i-1][j-w[i-1]];
//path代表的当背包容量为j时,第i个物品存放了一次的数组形式。
path[i][j] = 1;
}else{
v[i][j] = v[i -1][j];
}
}
}
}
//输出
for (int i = 0; i < v.length; i++) {
for (int j = 0; j < v[i].length; j++) {
System.out.print(v[i][j]+" ");
}
System.out.println();
}
System.out.println("11111111111111111");
for (int i = 0; i < path.length; i++) {
for (int j = 0; j < path[i].length; j++) {
System.out.print(path[i][j]+" ");
}
System.out.println();
}
System.out.println("11111111111111111");
//最后输出的商品,
int i = path.length -1;//物品的编号
int j = path[0].length - 1;//背包容量
while(i > 0 && j > 0){
if(path[i][j] == 1){
//path代表的当背包容量为j时,第i个物品存放了一次的数组形式。
//j为当前的背包容量,当符合调用的path时,j的容量就应该缩减为减去当前物品所表示的容量,
//然后,在对这个剩下的容量进行第i-1个,i-2个是否放入的判定,如果在 j -= w[i-1]还有剩下的空间,
//对前i个物品而言,就可以继续放入背包,知道j<=0为止;
///倒叙形式的物品寻找法
System.out.printf("第%d个商品放入背包\n", i);
j -= w[i-1];
}
i--;
}
}
}
JAVA