多重揹包問題 II

2021-10-06 16:13:33 字數 1416 閱讀 7441

有 n 種物品和乙個容量是 v 的揹包。

第 i 種物品最多有 si 件,每件體積是 vi,價值是 wi。

求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。

輸出最大價值。

輸入格式

第一行兩個整數,n,v,用空格隔開,分別表示物品種數和揹包容積。

接下來有 n 行,每行三個整數 vi,wi,si,用空格隔開,分別表示第 i 種物品的體積、價值和數量。

輸出格式

輸出乙個整數,表示最大價值。

輸入樣例:

451

2324

1343

452

輸出樣例:

10

那麼我們為什麼不能用上乙個問題的方法呢,因為資料範圍是很大。

時間複雜度是1000乘2000乘2000,那麼就是40億,而c++最多可以處理一億個資料,所以一定會超時。那麼我們就可以用二進位制優化。

怎麼優化呢?

比如s=1024,即這一組物品的個數。那麼我們想一想真的需要從0列舉到1024嗎,答案是否定的!我們可以將這些物品打包成10組。每一組最多只能選一次。

那麼這些組數為1,2,4,…,512. 我們就可以用這些組數來拼湊出從0~1024的任意乙個數字(如果用第一組,則我們可以拼湊出0到1這些數,那麼我們再加上第二組,那麼我們就可以拼湊出來2到3這些數,合起來就是0到3,以此類推我們就可以得到0到1024之間任意一種情況)。

所以說優化就是:把所有的這些物品劃分成若干組,每一組只能選或者不選。是不是和01揹包一模一樣呢?

自此,優化就完成了。

**如下:

#include

#include

using

namespace std;

const

int n =

25000

,m=2010

;int v[n]

,w[n]

,s[n]

;int f[n]

;int n,m;

intmain()

if(s>0)

//如果最後s還有剩餘,那麼加上剩餘的s就是完整的物品數。

} n=cnt;

for(

int i=

1;i<=n;i++

)for

(int j=m;j>=v[i]

;j--

) f[j]

=max

(f[j]

,f[j-v[i]

]+w[i]);

cout << f[m]

<< endl;

return

0;

多重揹包問題 II

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

多重揹包問題II

多重揹包問題ii 總體積是m,每個小物品的體積是a i 每個小物品的數量是b i 每個小物品的價值是c i 求能夠放入揹包內的最大物品能夠獲得的最大價值 和上乙個很類似 上一題體積就是價值,這裡的價值是單獨定義了 狀態轉移方程 不放a i f i j f i 1 j 放a j 可放多個設為k,k m...

多重揹包問題 II

原題鏈結acwing5 基本思考框架 思路和多重揹包問題i一樣,但這題的資料範圍變成1000了,非優化寫法時間複雜度o n 3 接近 1e9必超時。優化多重揹包的優化 首先,我們不能用完全揹包的優化思路來優化這個問題,因為每組的物品的個數都不一樣,是不能像之前一樣推導不優化遞推關係的。詳情看下面引用...