多重揹包問題 III
阿新 • • 發佈:2022-04-20
揹包九講(5)
多重揹包問題 III
有 N 種物品和一個容量是 V的揹包。
第 ii 種物品最多有 si 件,每件體積是 vi,價值是 wi。
求解將哪些物品裝入揹包,可使物品體積總和不超過揹包容量,且價值總和最大。
輸出最大價值。
輸入格式
第一行兩個整數,N,V (0<N≤1000,0<V≤20000),用空格隔開,分別表示物品種數和揹包容積。
接下來有 N 行,每行三個整數 vi,wi,si,用空格隔開,分別表示第 ii 種物品的體積、價值和數量。
輸出格式
輸出一個整數,表示最大價值。
資料範圍
0<N≤10000<N≤1000
0<V≤200000<V≤20000
0<vi,wi,si≤200000<vi,wi,si≤20000
提示
本題考查多重揹包的單調佇列優化方法。
輸入樣例
4 5
1 2 3
2 4 1
3 4 3
4 5 2
輸出樣例:
10
想不通,先給出答案,以後能看懂再說吧,利用單調佇列去優化,思路比較困難。
#include<iostream> #include<algorithm> #include<vector> #include<cstring> using namespace std; const int N = 20010; int n,m; int f[N],g[N],q[N]; int main(){ cin>>n>>m; for(int i=0;i<n;i++){ int c,w,s; cin>>c>>w>>s; memcpy(g,f,sizeof(f)); for(int j=0;j<c;j++){ int hh=0,tt=-1; for(int k=j;k<=m;k+=c){ f[k]=g[k]; if(hh<=tt&&k-s*c>q[hh])hh++; if(hh<=tt)f[k]=max(f[k],g[q[hh]]+(k-q[hh])/c*w); while(hh<=tt&&g[q[tt]]-(q[tt]-j)/c*w<=g[k]-(k-j)/c*w)tt--; q[++tt]=k; } } } cout<<f[m]; return 0; }