http://acm.hdu.edu.cn/showproblem.php?pid=3732
先用01背包 超时,,v,c的范围只有11个可以转化成多重背包。
memset(dp,0,sizeof(0))~~~汗sizeof(0)wa了10次。。。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int dp[200005];
int num[15][15];
int m;
void CompletePack(int c,int v)
{
int i;
for(i=c;i<=m;i++)
dp[i]=max(dp[i],dp[i-c]+v);
}
void ZeroOnePack(int c,int v)
{
int i;
for(i=m;i>=c;i--)
{
dp[i]=max(dp[i],dp[i-c]+v);
}
}
int main()
{
int n;
while(scanf("%d%d",&n,&m)!=EOF)
{
int i;
char str[20];
memset(num,0,sizeof(num));
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
int t1,t2;
scanf("%s %d %d",str,&t1,&t2);
num[t1][t2]++;
}
int j;
for(j=0;j<=10;j++)
{
for(i=0;i<=10;i++)
{
if(num[i][j]==0)
continue;
if(j*num[i][j]>=m)
CompletePack(j,i);
else
{
int k=1;
while(k<=num[i][j])
{
ZeroOnePack(k*j,k*i);
num[i][j]=num[i][j]-k;
k=k*2;
}
if(num[i][j])
ZeroOnePack(num[i][j]*j,num[i][j]*i);
}
}
}
printf("%d\n",dp[m]);
}
return 0;
}