【動態規劃】01揹包問題

問題描述:給定一組物品,每種物品都有自己的重量和價格,在限定的總重量內,我們如何選擇,才能使得物品的總價格最高。 

物品編號 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
 */

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章