有 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必超時。優化多重揹包的優化 首先,我們不能用完全揹包的優化思路來優化這個問題,因為每組的物品的個數都不一樣,是不能像之前一樣推導不優化遞推關係的。詳情看下面引用...