有N件物品和一個容量爲V的揹包。第i件物品的體積是c[i],價值是w[i]。求解將哪些物品裝入揹包可以使價值總和最大。
從這個題目中能夠看出,01揹包的特色就是:每種物品僅有一件,能夠選擇放或不放。
其狀態轉移方程是:html
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
要理解上面的那個公式,須要學會填表。
假設java
n=5, C=13, w={4,5,4,3,10}, v={9,10,9,2,24}
假如揹包要放第i件物品,
此時若是不放第i件物品,那麼問題就轉化爲「前i-1件物品放入重量是w的揹包中」,價值爲f[i-1,j];
若是放第i件物品,那麼問題就轉化爲「前i-1件物品放入剩下的重量爲j-Wi的揹包中」,此時能得到的最大價值就是f[i-1,j-Wi]再加上經過放入第i件物品得到的價值Pi,此時只要比較f[i-1,j]和f[i-1,j-Wi]+Pi那個大就能獲取到揹包裏最大的價值是多少了。數組
public class Test { public static int getMaxValue(int[] weight, int[] value, int w, int n) { // 建立一個二維數組,橫列是物品的價值,豎列是物品的重量 int[][] table = new int[n + 1][w + 1]; for (int i = 1; i <= n; i++) { //物品 for (int j = 1; j <= w; j++) { //揹包大小 if (weight[i] > j) { //當前物品i的重量比揹包容量j大,裝不下,確定就是不裝 table[i][j] = table[i - 1][j]; } else { //裝得下,Max{裝物品i, 不裝物品i} table[i][j] = Math.max(table[i - 1][j], table[i - 1][j - weight[i]] + value[i]); } } } return table[n][w]; } public static void main(String[] args) { int n = 5, w = 13; //物品個數,揹包容量 int[] value = {0,9,10,9,2,24}; //各個物品的價值 int[] weight = {0,4,5,4,3,10}; //各個物品的重量 System.out.println(getMaxValue(weight, value, w, n)); } }