您的位置:首页 > 产品设计 > UI/UE

HDU 3732 Ahui Writes Word

2015-10-07 19:57 507 查看
乍一看是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\n", f[C]);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: