揹包問題之最優方案總數

此處的最優方案是指物品總價值最大的方案。這裏以0-1揹包問題爲例。給定數據如下:

c = [2,3,4,5,6,7,8];
v = [3,4,5,6,7,8,9];
V = 23;

結合求最大總價值和方案總數兩個問題的思路,最優方案的總數可採取如下方式求解:令 dp[i][j]dp[i][j] 表示前 i 件物品在代價爲 j 時的最大價值,key[i][j]key[i][j] 表示這個子問題的最優方案的總數。那麼可以在求解 dp[i][j]dp[i][j] 的同時求 key[i][j]key[i][j]。分爲以下幾種情況:

  • dp[i][j]==dp[i1][j]dp[i][j]==dp[i-1][j] 或者 dp[i][j]==dp[i1][jc[i]]+v[i]dp[i][j]==dp[i-1][j-c[i]]+v[i],則 key[i][j]key[i][j] 等於對應最優方案總數。
  • dp[i1][j]==dp[i1][jc[i]]+v[i]dp[i-1][j]==dp[i-1][j-c[i]]+v[i],那麼 key[i][j]=key[i1][j]+key[i1][jc[i]]key[i][j]=key[i-1][j]+key[i-1][j-c[i]]
    public int knapsackProblem(int[] c, int[] v, int V) {
        int[][] dp = new int[c.length + 1][V + 1], key = new int[c.length + 1][V + 1];
        for (int i = 0; i < key.length; i++) {
            Arrays.fill(key[i], 1);	// 初始化爲1的目的是保證任何情況下,dp[i][j]總是存在的,存在則至少爲1。
        }
        for (int i = 1; i <= c.length; i++) {
            for (int j = V; j > 0; j--) {
                dp[i][j] = dp[i - 1][j];
                key[i][j] = key[i - 1][j];
                if (j >= c[i - 1]) {
                    if (dp[i][j] < dp[i - 1][j - c[i - 1]] + v[i - 1]) {
                        dp[i][j] = dp[i - 1][j - c[i - 1]] + v[i - 1];
                        key[i][j] = key[i - 1][j - c[i - 1]];
                    } else if (dp[i][j] == dp[i - 1][j - c[i - 1]] + v[i - 1]) {
                        key[i][j] += key[i - 1][j - c[i - 1]];
                    }
                }
            }
        }
        System.out.println("最優方案總數: " + key[c.length][V]);
        return dp[c.length][V];
    }

上一篇:揹包問題之輸出最優方案

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