题目描述:
有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和?
图片理解:
先来看图片,从name=e的这一行开始,这一行的意思是,在只有e的情况下,背包大小从1增大到10,与对应的背包中的最大价值。
倒数第二行意思是,只有d,e的情况下,背包大小从1增大到10,与对应的背包中的最大价值。
以此类推。
算法分析:
以倒数第二行(后写为now)的求法为例,算法为:从 当背包大小为d.weight时开始,也就是5开始,对比倒数第一行(后写为before),如果before[5] < before[5 - d.weight] + d.value,则让now[5] = before[5 - d.weight] + d.value,否则不改变。
再看before[6],如果before[6] < before[6 - d.weight] + d.value,则让now[6] = before[6 - d.weight] + d.value,否则不改变。
以此类推。
这就是动态规划,步步为营,循序渐进。
public class BagProblem {
private int[] weight;
private int[] value;
private int[] bag;
public BagProblem(int[] weight, int[] value, int[] bag) {
// TODO Auto-generated constructor stub
this.weight = weight;
this.value = value;
this.bag = bag;
}
public boolean excute() {
if(weight == null || value == null || bag == null || weight.length != value.length)
return false;
for(int j = 1; j < value.length; j++) {
//注意这里用到了克隆
int[] bagclone = bag.clone();
for(int i = weight[j]; i < bag.length; i++) {
if(bagclone[i] < bagclone[i - weight[j]] + value[j]) {
bag[i] = bagclone[i - weight[j]] + value[j];
}
}
}
return true;
}
public void print() {
if(bag != null) {
for(int i : bag) {
System.out.print(i + " ");
}
}
}
public static void main(String[] args) {
BagProblem bagProblem = new BagProblem(new int[] {0,2,2,6,5,4}, new int[] {0, 6,3,5,4,6}, new int[11]);
bagProblem.excute();
bagProblem.print();
}
}