泛化物品是指该物品的价值与其体积存在一一对应的关系,即该物品的价值随着体积的变化而变化,是一种函数关系。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); }
未完待续。