题意:
很简单,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;
}