問題描述:給定一組物品,每種物品都有自己的重量和價格,在限定的總重量內,我們如何選擇,才能使得物品的總價格最高。
物品編號 | 1 | 2 | 3 | 4 | 5 |
體積(weight) | 48 | 7 | 40 | 12 | 8 |
價值(value) | 6 | 1 | 5 | 2 | 1 |
這個題是很典型的一個動態規劃的題目,動態規劃題目的題就是找好初始條件和結束條件以及狀態轉移方程。也就是類似於由小推大的方式。我們這裏定義一個二維數組v用來存儲最大價值,數組的第一維表示的是當前存放i個物品,第二維表示當前揹包的空間是j。v[i][j]表示的是當用前i個物品爲候選物品,揹包的空間是j的時候的最大價值,由此可知該二維數組存放的最後一個值就爲該題目的結果。
狀態轉移方程:
if (揹包體積j小於物品i的體積)
//揹包裝不下第i個物體,所以其結果和前i-1個物體的結果是一樣的
v[i][j] = v[i-1][j];
else
v[i][j] = Math.max(v[i - 1][j], v[i - 1][j - weight[i]] + value[i]);
public static void main(String[] args) {
//int[] weight = {1, 12};
//這裏爲了保證v中存放的行列值和重量價值對應的索引對應上所以用0放到了前面,因爲數組索引是從0開始的
int[] weight = {0, 6, 1, 5, 2, 1};
//int[] value = {2, 4};
int[] value = {0, 48, 7, 40, 12, 8};
int capacity = 8; //容量
System.out.println(maxValue(weight, value, capacity));
}
public static int maxValue(int[] weight, int[] value, int capacity) {
int weightLen = weight.length;
int valueLen = capacity + 1;//列值長度加1,是因爲最後一列的列值和重量值相對應
int maxValue = 0;
int[][] v = new int[weightLen][valueLen];
for (int i = 1; i < weightLen; i++) {
for (int j = 1; j < valueLen; j++) {
if (i == 0 || j == 0)
v[i][j] = 0;
if (weight[i] <= j) {
v[i][j] = Math.max(v[i - 1][j], v[i - 1][j - weight[i]] + value[i]);
} else {
v[i][j] = v[i - 1][j];
}
maxValue = v[i][j];
}
}
// for (int i = 0; i < weightLen; i++) {
// for (int j = 0; j < valueLen; j++) {
// System.out.print(v[i][j] + " ");
// }
// System.out.println();
// }
return maxValue;
}
/**
* v存儲的結果
* 0 0 0 0 0 0 0 0 0
* 0 0 0 0 0 0 48 48 48
* 0 7 7 7 7 7 48 55 55
* 0 7 7 7 7 40 48 55 55
* 0 7 12 19 19 40 48 55 60
* 0 8 15 20 27 40 48 56 63
*/