泛化物品是指該物品的價值與其體積存在一一對應的關係,即該物品的價值隨着體積的變化而變化,是一種函數關係。php
例如,在01揹包中,最後的答案數組其實就是一個泛化物品。ios
有泛化物品\(f,g\),他們的並是相同體積下價值的最大值。設f體積爲fv,g體積爲gv,把並後的泛化物品從新賦值給fc++
代碼:數組
int v=Max(fv,gv); for(int i=1;i<=v;i++) f[i]=Max(f[i],g[i]);
此過程相似於01揹包,f爲泛化物品,fv爲其最大致積,v,c分別爲普通物體的體積,價值。函數
代碼:spa
for(int i=1;i<=fv;i++) f[i+v]=Max(f[i+v],f[i]+c);
此過程要枚舉當前的整體積,和分給第一個泛化物品的體積,結果取最值。code
設f,g兩個泛化物品的合併爲h,fv,gv定義如上。get
代碼:string
for(int i=0;i<=v;i++) for(int j=0;j<=i;j++) h[i]=Max(h[i],g[j]+f[i-j]);
http://ybt.ssoier.cn:8088/problem_show.php?pid=1272it
能夠發現,每一組中其實都是一個泛化揹包,價值隨着體積的變化而變化。
把一個組轉化爲一個泛化揹包只有一點須要注意,若是體積有剩餘,價值與前面的同樣。詳細看代碼。
轉換完以後,對n個泛化揹包進行合併。輸出結果。有了泛化揹包這個概念後明顯好理解了許多。
代碼:
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> #include<sstream> #include<queue> #include<map> #include<vector> #include<set> #include<deque> #include<cstdlib> #include<ctime> #define dd double #define ll long long #define ull unsigned long long #define N 11 #define M 201 using namespace std; int v,n,t; int h[N][M]; inline int Max(int a,int b){ return a>b?a:b; } int main(){ scanf("%d%d%d",&v,&n,&t); for(int i=1;i<=n;i++){ int w,c,p; scanf("%d%d%d",&w,&c,&p); h[p][w]=Max(h[p][w],c); } for(int i=1;i<=t;i++){ int now=0; for(int j=0;j<=v;j++){ now=Max(now,h[i][j]); h[i][j]=now; } } // for(int i=1;i<=t;i++){ // for(int j=0;j<=v;j++) printf("%d ",h[i][j]); // printf("\n"); // } for(int i=2;i<=t;i++){ for(int j=v;j>=0;j--) for(int k=0;k<=j;k++) h[i][j]=Max(h[i][j],h[i-1][k]+h[i][j-k]); // printf("new i:%d ",i); // for(int j=0;j<=v;j++) printf("%d ",h[i][j]); // printf("\n"); } printf("%d",h[t][v]); return 0; }
http://ybt.ssoier.cn:8088/problem_show.php?pid=1267
for(int i=1;i<=n;i++) { int w,c; scanf("%d%d",&w,&c); for(int j=m;j>=w;j--) { f[j]=max(f[j],f[j-w]+c); } }
http://ybt.ssoier.cn:8088/problem_show.php?pid=1268
for(int i=1;i<=n;i++) { int w,c; scanf("%d%d",&w,&c); for(int j=w;j<=m;j++) { f[j]=max(f[j],f[j-w]+c); } }
http://ybt.ssoier.cn:8088/problem_show.php?pid=1270
for(int i=1;i<=n;i++) { int w,c,p; scanf("%d%d%d",&w,&c,&p); if(p==1) a[++tail].intt(w,c,1); else if(p==0) a[++tail].intt(w,c,0); else { for(int j=1;j<=p;j*=2) { p-=j; a[++tail].intt(j*w,j*c,1); } if(p) a[++tail].intt(p*w,p*c,1); } } for(int i=1;i<=tail;i++) { if(a[i].p==1) for(int j=m;j>=a[i].w;j--) f[j]=max(f[j],f[j-a[i].w]+a[i].c); else for(int j=a[i].w;j<=m;j++) f[j]=max(f[j],f[j-a[i].w]+a[i].c); }
未完待續。