多重揹包問題 III

2022-07-09 08:30:28 字數 2227 閱讀 7021

演算法1

(單調佇列優化) o(nv)

一共是n類物品,揹包的容量是m

每類物品的體積為v, 價值為w,個數為s

我們先來回顧一下傳統的dp方程

dp[i][j] 表示將前 i 種物品放入容量為 j 的揹包中所得到的最大價值

dp[i][j] = max(不放入物品 i,放入1個物品 i,放入2個物品 i, ... , 放入k個物品 i)

這裡 k 要滿足:k <= s, j - k*v >= 0

不放物品 i = dp[i-1][j]

放k個物品 i = dp[i-1][j - k*v] + k*w

dp[i][j] = max(dp[i-1][j], dp[i-1][j-v] + w, dp[i-1][j-2*v] + 2*w,..., dp[i-1][j-k*v] + k*w)

實際上我們並不需要二維的dp陣列,適當的調整迴圈條件,我們可以重複利用dp陣列來儲存上一輪的資訊

我們令 dp[j] 表示容量為j的情況下,獲得的最大價值

那麼,針對每一類物品 i ,我們都更新一下 dp[m] --> dp[0] 的值,最後 dp[m] 就是乙個全域性最優值

dp[m] = max(dp[m], dp[m-v] + w, dp[m-2*v] + 2*w, dp[m-3*v] + 3*w, ...)

接下來,我們把 dp[0] --> dp[m] 寫成下面這種形式

dp[0], dp[v],   dp[2*v],   dp[3*v],   ... , dp[k*v]

dp[1], dp[v+1], dp[2*v+1], dp[3*v+1], ... , dp[k*v+1]

dp[2], dp[v+2], dp[2*v+2], dp[3*v+2], ... , dp[k*v+2]

...dp[j], dp[v+j], dp[2*v+j], dp[3*v+j], ... , dp[k*v+j]

顯而易見,m 一定等於 kv + j,其中 0 <= j < v

所以,我們可以把 dp 陣列分成 j 個類,每一類中的值,都是在同類之間轉換得到的

也就是說,dp[kv+j] 只依賴於

因為我們需要的是中的最大值,

可以通過維護乙個單調佇列來得到結果。這樣的話,問題就變成了 j 個單調佇列的問題

所以,我們可以得到

dp[j]    =     dp[j]

dp[j+v] = max(dp[j] + w, dp[j+v])

dp[j+2v] = max(dp[j] + 2w, dp[j+v] + w, dp[j+2v])

dp[j+3v] = max(dp[j] + 3w, dp[j+v] + 2w, dp[j+2v] + w, dp[j+3v])

...

但是,這個佇列中前面的數,每次都會增加乙個 w ,所以我們需要做一些轉換

dp[j]    =     dp[j]

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

dp[j+2v] = max(dp[j], dp[j+v] - w, dp[j+2v] - 2w) + 2w

dp[j+3v] = max(dp[j], dp[j+v] - w, dp[j+2v] - 2w, dp[j+3v] - 3w) + 3w

...

這樣,每次入隊的值是dp[j+k*v] - k*w單調佇列問題,最重要的兩點

1)維護佇列元素的個數,如果不能繼續入隊,彈出隊頭元素

2)維護佇列的單調性,即:尾值 >= dp[j + kv] - kw

本題中,佇列中元素的個數應該為 s+1 個,即 0 -- s 個物品 i

c++ **

#include #include using namespace std;

const int n = 20010;

int dp[n], pre[n], q[n];

int n, m;

int main() }}

cout << dp[m] << endl;

return 0;

}

揹包模型 多重揹包問題 III

有 nn 種物品和乙個容量是 vv 的揹包。第 ii 種物品最多有 sisi 件,每件體積是 vivi 價值是 wiwi 求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。輸出最大價值。輸入格式第一行兩個整數,n,vn,v 0,0,用空格隔開,分別表示物品種數和揹包容積。接下來...

多維多重揹包問題 多重揹包問題

悼念512汶川大 遇難同胞 珍惜現在,感恩生活 急!災區的食物依然短缺!為了挽救災區同胞的生命,心繫災區同胞的你準備自己採購一些糧食支援災區,現在假設你一共有資金n元,而市場有m種大公尺,每種大公尺都是袋裝產品,其 不等,並且只能整袋購買。請問 你用有限的資金最多能採購多少公斤糧食呢?後記 人生是乙...

揹包問題 多重揹包

有n種物品和乙個容量為w的揹包。第i種物品最多有n i 件可用,每件重量是w i 價值是v i 求解將哪些物品裝入揹包可使這些物品的重量總和不超過揹包容量,且價值總和最大。1.使用三重迴圈進行遞推 狀態轉移式為 dp i j max 關鍵 如下 void solve printf d n dp n ...