乍一看是01背包,但是100000*10000的复杂度肯定是TLE的,但是(0 ≤ Vi , Ci ≤ 10),所以最多也只有100种物品,转化成多重背包去做。
#include#include #include int N,C,vv,cc;int g[15][15];char s[100];int w[105],c[105],n1[105];int tot;int f[10000+10];int max(int a,int b){ if(a>b) return a; else return b;}void ZeroOnePack(int c, int w){ for (int v = C; v >= c; v--) { f[v] = max(f[v], f[v-c] + w); }}//完全背包void CompletePack(int c, int w){ for (int v = c; v <= C; v++) { f[v] = max(f[v], f[v-c] + w); }}//多重背包,二进制。void MultiplePack(int c, int w, int n1){ if (c * n1 >= C) { CompletePack(c, w); } else { int k = 1; while (k < n1) { ZeroOnePack(k*c, k*w); n1 -= k; k <<= 1; } ZeroOnePack(n1*c, n1*w); }}int main(){ while(~scanf("%d%d",&N,&C)) { memset(g,0,sizeof g); tot=0; for(int i=1;i<=N;i++) { scanf("%s%d%d",s,&vv,&cc); g[vv][cc]++; } for(int i=0;i<=10;i++) { for(int j=0;j<=10;j++) { if(g[i][j]>0) { w[tot]=i; c[tot]=j; n1[tot]=g[i][j]; tot++; } } } memset(f, 0, sizeof(f)); for (int i = 0; i < tot; i++) MultiplePack(c[i], w[i], n1[i]); printf("%d\n", f[C]); } return 0;}