码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 3732 Ahui Writes Word

时间:2015-10-07 20:16:13      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:

乍一看是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;
}

 

HDU 3732 Ahui Writes Word

标签:

原文地址:http://www.cnblogs.com/zufezzt/p/4859259.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!