揹包九講之 01揹包

2021-10-03 10:45:09 字數 1080 閱讀 6036

01揹包是最基礎的揹包問題,其中01代表的就是第i個物品的選或不選,在此先設v[i]為體積,w[i]為價值。

很顯然,我們可以使用二位陣列dp[i][j]來表示前i個物品在揹包容量為j的時候可存放的最大價值。首先dp[0][0]=0是很顯然的。而計算dp[i][j]時,存在01兩種情況:選或不選第i件物品。

1.不選第i件物品:dp[i][j]=dp[i-1][j];那麼此時的價值就是前i件物品容量為j的時候價值,不難理解。

2.選第i件物品:dp[i][j]=dp[i-1][j-v[i]]+w[i];此時的價值為前i件物品容量為j-v[i]的容量。

由此得出狀態轉移方程:dp[i][j]=max(dp[i-1][j],dp[i-1][j-v[i]]+w[i]);遍歷計算出dp[n][m]即可。

dp[0]

[0]=

0;for(

int i=

1;i<=n;i++

)//n為物品數

}cout<[m];

//dp[n][m]顯然為結果

由上可以看出為o(n*m)的複雜度,可以優化,那麼二位的dp優化的方向便是向一維優化。由dp[i][j]->dp[j],表示容量為j的揹包所裝物品的最大價值,從上述基礎**做優化。

dp[0]

=0;for

(int i=

1;i<=n;i++

)//n為物品數

/*考慮為什麼內層迴圈變成相反方向迴圈?

因為若是從小往大迴圈,那麼dp[j]=max(dp[j],dp[j-v[i]]+w[i]);中的dp[j-v[i]],j-v[i]是小於j的,

因此dp[j-v[i]]在本次i的迴圈中已經先於j被計算過,

那就是說dp[j-v[i]]可能其中已經包含了第i件物品,

那麼再次計算dp[j]時可能會重複加上第i件物品;

換句話說,此時的dp[j-v[i]]是dp[i][j-v[i]]

而非dp[i-1][j-v[i]]。當反向從大到小遍歷時

則會避免這個問題。*/

}cout<;

以上就是01揹包的基本講解了,若有不足還望海涵並指出

DP 揹包九講之01揹包

有n件物品和乙個容量為v 的揹包。放入第i件物品耗費的空間是ci,得到 的價值是wi。求解將哪些物品裝入揹包可使價值總和最大。這是最基礎的揹包問題,特點是 每種物品僅有一件,可以選擇放或不 放。用子問題定義狀態 即f i,v 表示前i件物品恰放入乙個容量為v的揹包可以 獲得的最大價值。則其狀態轉移方...

DP 揹包九講之01揹包

有 n 件物品和乙個容量是 v 的揹包。每件物品只能使用一次。第 i 件物品的體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最大價值。輸入格式 第一行兩個整數,n,v,用空格隔開,分別表示物品數量和揹包容積。接下來有 n 行,每行兩個整數 ...

DP 揹包九講之01揹包

有 n 件物品和乙個容量是 v 的揹包。每件物品只能使用一次。第 i 件物品的體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最大價值。輸入格式 第一行兩個整數,n,v,用空格隔開,分別表示物品數量和揹包容積。接下來有 n 行,每行兩個整數 ...