動態規劃 多重揹包

2021-09-26 11:05:00 字數 1726 閱讀 7453

概念

多重揹包:有n種物品和乙個容量為v的揹包。第i種物品最多有n[i]件可用,每件費用是c[i],價值是w[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,並且價值總和最大。這類問題即為多重揹包問題。

把多重揹包當成01揹包

我們樸素的想法就是,對於某一種物品,我們看取乙個的時候,跑一遍,取兩個的時候,跑一遍,一共跑與它個數相同的遍數,然後就繼續下乙個物品,直到結束,這樣也能求解,但是時間效率上不夠快。

多重揹包二進位制分解思想

我們的樸素的想法是把它當成01揹包,不過時間效率不高,所以用二進位制分解的思想來求解。

這個思想算是很簡單的。

我們知道,對於多重揹包問題,每乙個物品都有它的價值和個數對吧。

這裡假設目前這個物品價值為a[i],個數為c[i],那麼我們肯定能用1個,2個,4個,8個……這樣的(二進位制)組合,把c[i]的每一種取法(取1、2、3、4……c[i]個)都表示出來。

那麼我把某種物品,一共c[i]個,可以分解為多種物品,每種只有乙個,並且第一種的價值為a[i],第二種物品的價值為2a[i],第三種物品的價值為4a[i]……。

單調佇列優化

時間複雜度為o(vn)

舉例

hdu - 2191 多重揹包模板題

**

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int maxn =

1e2+5;

int dp[maxn]

;int p[maxn]

, val[maxn]

, c[maxn]

;int

main()

return0;

}

hdu - 2844 多種揹包模板題,用二進位制分解的思想解決

#include

#include

#include

#include

#include

using

namespace std;

typedef

long

long ll;

const

int maxn =

1e5+5;

int dp[maxn]

;int a[

105]

;int c[

105]

;int

main()

if(c[i]

>0)

}int ans =0;

for(

int i =

1; i <= m; i++)if

(dp[i]

== i)

ans++

;printf

("%d\n"

, ans);}

return0;

}

部落格–轉化成01揹包,很好懂

部落格–轉化為01揹包,很好懂

部落格–單調佇列優化

揹包九講

多重揹包的二進位制分解思想

動態規劃 多重揹包

動態規劃 多重揹包 時間限制 1 sec 記憶體限制 64 mb 提交 5 解決 5 提交 狀態 討論版 張琪曼 魔法石礦裡每種魔法石的數量看起來是足夠多,但其實每種魔法石的數量是有限的。李旭琳 所以我們需要改變裝包策略啦。現有n n 10 種魔法石和乙個容量為v 0第一行為兩個數字,即v和n。以下...

動態規劃4 多重揹包

1.這裡區別一下三種揹包 1 01揹包 揹包有最大容量c,給出n種物品,每種物品僅僅乙個,有自己的重量和價值wi和vi,求揹包可裝下的最大價值 2 完全揹包 揹包有最大容量c,給出n種物品,每種物品無限個,有自己的重量和價值wi和vi,求揹包可裝下的最大價值 3 多重揹包 揹包有最大容量c,給出n種...

動態規劃 多重揹包問題

有 n 種物品和乙個容量為 w 的揹包,每種物品都有無限件可用。第 i 種物品的重量是 w i 價值是 v i 最多有 s i 件 求解將哪些物品裝入揹包可使這些物品的重量總和不超過揹包容量,且價值總和最大。第一行兩個整數,n 和 v 用空格隔開,分別表示物品總數和揹包的容積 接下來有 n 行。每行...