01揹包的學習

問題描述:

          有 n 個重量和價值分別爲 w[i],  v[i] 的物品。從這些物品中挑選出總重量不超過 W 的物品, 所求有挑選方案中價值中價值總和的最大值。

         (限制條件:1 <= n <= 100, 1 <= w[i], v[i] <= 100, 1 <= W <= 10000)

輸入:

4 5  (n, W)

2 3  (w[i],  v[i])

1 2

3 4

2 2

輸出:

7

每一件物品有兩種結果:放入或是不放入揹包。於是可以用搜索來解決。

但是這樣會產生高度爲 n 這樣大的遞歸樹,在限制的時間內會無法完成。看一下這樣產生的樹:


這樣的搜索會有重複調用,造成時間和空間上的浪費。

對於這種情況,可以採用動態規劃的方式解決。(動態規劃:把多階段過程轉化爲一系列單階段問題,利用各階段之間的關係,逐個求解)

從第i個物品開始挑選總重小於j時,總價值的最大值,其遞推式:

dp[n][j] = 0;

j < w[i] :

             dp[i][j] = dp[i+1][j]

其他:

             dp[i][j] = max( dp[ i+1 ][j] ,  dp[ i+1 ][ j-w[i] ] + v[i]

void fun()
{
    for (int i = n-1; i >= 0; i--)
    {
        for (int j = 0; j <= W; j++)
        {
            if (j < w[i])
                dp[i][j] = dp[i+1][j];
            else
                dp[i][j] = max(dp[i+1][j], dp[i+1][j-w[i]] + v[i]);
        }
    }
    printf("%d\n", dp[0][W]);
}
參考書籍 :《挑戰程序設計競賽》

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