大家都知道的多重揹包與混合揹包

2021-10-05 11:23:06 字數 2971 閱讀 9543

多重揹包2

混合揹包

與01揹包不同的是,多重揹包的每乙個物品有s件,而01揹包每個物品有1件。

我們是不是可以進行乙個拆分,把這s件物品拆成01揹包的模型來計算。

我們再看物品的數量,假設最多的100件物品,每個物品可以取100次,我們使用三重迴圈的話,時間複雜度是100 * 100 * 100,也就是10的6次方。而c++程式一秒大概可以執行10的7次方 ~ 10的8次方左右的次數。

也就是說我們簡單使用三重迴圈的暴力方法是可以過的。

看了一眼資料範圍,1000 * 2000 * 2000,直接暴力三重迴圈肯定超時了。

提示中顯示,可以使用二進位制優化的方法,也就是使用二進位制對揹包進行壓縮。

我們直接把所有物品都變成乙個乙個的肯定不行,我們可以利用二進位制獨特的壓縮方式,可以把多個物品壓縮成乙個物品,這樣物品的數量壓縮的範圍簡化到1000 * log(2000),時間複雜度近似於1000 * 11 * 2000,我們看這是可以在1s 中跑完的,時間複雜度可以通過了。

;//存放壓縮後物品的倉庫

typedef

struct good

good;

intmain()

);s -

= k;

}//不能分解的,單獨構成乙個物品

if(s) goods.

push_back()

;}//安裝01揹包的模板進行遍歷

我們可以看到,在這個題中,乙個物品有三種型別,一種可以使用1次(01揹包),一種可以使用無限次(完全揹包),最後一種可以使用多次(多重揹包)。

而且時間複雜度也是挺高的,1000 * 1000 * 1000,10的9次方,已經超過了c++1秒的執行次數。

和上面的多重揹包問題相同,我們可以採用壓縮的方式,將多重揹包都利用二級制的思想壓縮為01揹包,然後分情況來解決混合揹包的問題。我們就把題目變成了01揹包和完全揹包的情況。

時間複雜度1000 * 11 * 1000 + 1000 * 1000,這是完全可以的。

#include

#include

#include

using

namespace std;

const

int n =

10010

;struct good

;vector goods;

int dp[n]

;int

main()

);else);

s -= k;}if

(s) goods.

push_back()

;}}//計算

for(

int i =

0; i < goods.

size()

; i++)if

(goods[i]

.s ==-1

)//01揹包

for(

int j = m; j >= goods[i]

.v; j--

) dp[j]

=max

(dp[j]

, dp[j - goods[i]

.v]+ goods[i]

.w);

else

//多重揹包問題

for(

int j = goods[i]

.v; j <= m; j++

) dp[j]

=max

(dp[j]

, dp[j - goods[i]

.v]+ goods[i]

.w);

cout<

<

return0;

}

0 1 完全揹包 多重揹包問題 混合揹包

0 1揹包問題 dp i j 表示前i件物品,體積容量為j的揹包所能獲得的最大價值 決策是第i個物品選不選 轉移方程 dp i j max dp i 1 j dp i 1 j v i w i n為物品數量,m為揹包體積 for int i 1 i n i for int j 0 j m j if j...

大家都知道的01揹包問題

一維解法 拓展問題 完全揹包 對於每乙個物品,在揹包容量足夠的情況下,我們有兩種狀態,一種是把該物品放在揹包,一種是不把該物品放在揹包。我們建立乙個二維的陣列,dp i j 表示前 i 個物品,在容量為 j 的時候,最大價值。v i 表示物品所佔的體積 w i 表示物品的價值 把該物品放在揹包 dp...

揹包學習 多重揹包揹包

有n種物品和乙個容量為v的揹包。第i種物品最多有n i 件可用,每件費用是c i 價值是w i 求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包容量,且價值總和最大。狀態轉移方程 f i v max 此時他面臨的不是01揹包的選與不選的問題,而是從n i 裡面選多少個的問題。實現方法 1 轉化...