点击打开链接
题意:
很简单,n件物品,背包大小为C,每件物品有一定的价值和体积,求背包能装的最大价值。。
很明显的01背包,但是如果用01的模板来做,绝对要超时的,因为n<=100000,C<=10000。
但是是不是就不能做了呢,我们可以发现每件物品的价值和体积都<=10,所以我们可以根据价值和体积来区分物品,而不用标号。
但是这样就解决问题了么,还没有,当我们跟据价值和体积来区分物体的时候,还是可能有100000物品的可能,这时候就要涉及一个新的东西了,
多重背包的二进制优化,比如一件物品有13件,我们可以把这种物品分成1件,2件,4件,6件,这四种物品,这四种物品的价值分别为件数*单件的价值,然后按照01背包计算就可以了。。
#include"stdio.h" #include"string.h" #define N 11 int A[N][N]; int dp[10005]; int max(int a,int b) { return a>b?a:b; } int main() { int n,C; int i,j,k; while(scanf("%d%d",&n,&C)!=-1) { memset(A,0,sizeof(A)); char s[11]; for(i=0;i<n;i++) { scanf("%s%d%d",s,&j,&k); getchar(); A[j][k]++; } memset(dp,0,sizeof(dp)); for(int v=0;v<=10;v++) { for(int c=0;c<=10;c++) { int t=A[v][c]; int k=1; if(t==0)continue; while(k<t) { for(i=C;i>=k*c;i--) dp[i]=max(dp[i],dp[i-k*c]+k*v); t-=k; k*=2; } for(i=C;i>=t*c;i--) dp[i]=max(dp[i],dp[i-t*c]+t*v); } } printf("%d\n",dp[C]); } return 0; }