乍一看是01背包,但是100000*10000的复杂度肯定是TLE的,但是(0 ≤ Vi , Ci ≤ 10),所以最多也只有100种物品,转化成多重背包去做。
#include<cstdio> #include<cstring> #include<cmath> 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 ", f[C]); } return 0; }