HDU 3732 多重背包

来源:互联网 发布:怎么样在淘宝网领金币 编辑:程序博客网 时间:2024/06/07 03:45

 这道题目意思很简单就是:输入 N 和 C ,N是代表N行,而C是复杂性,输入一些单词,然后告诉这些单词的价值,还有这些单词的复杂性! 一开始我一看这个题目就以为是01背包,然后就马上写完,第一组测试数据过了,但是却WA!后来看别人的博客,发现用多重背包,就想想,后来想通了,首先用01背包做第一组数据之所以能过,是因为第一组数据没有给出重复的单词,如果给出重复的单词就会出现数目的问题,就不能用01背包,而且数量还是有限的,所以就用多重背包!!1这题纯粹就是一个假的01背包!!!我感觉这道题目蛮好的!!!代码如下:#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=100005;int value[maxn],cost[maxn],num[12][12];int f[maxn];char s[15];int n,c;void zeropack(int value1, int cost1){    for(int i=c; i>=cost1; i--)    {        f[i]=max(f[i],f[i-cost1]+value1);    }}void completpack(int value1,int cost1){    for(int i=cost1; i<=c; i++)    {        f[i]=max(f[i],f[i-cost1]+value1);    }}void multiplepack(int value1,int cost1,int num1){    if(cost1*num1>=c)    {        completpack(value1,cost1);        return;    }    else    {        int k=1;        while(k<num1)        {            zeropack(k*value1,k*cost1);            num1=num1-k;            k=k*2;        }        zeropack(num1*value1,num1*cost1);    }}int main(){    int i,j;    while(scanf("%d%d",&n,&c)!=EOF)    {        memset(value,0,sizeof(value));        memset(cost,0,sizeof(cost));        memset(num,0,sizeof(num));        getchar();        for(i=0; i<n; i++)        {            scanf("%s%d%d",s,&value[i],&cost[i]);            num[value[i]][cost[i]]++;        }        memset(f,0,sizeof(f));        for(i=0; i<=10; i++)        {            for(j=0; j<=10; j++)            {                if(num[i][j])                {                    multiplepack(i,j,num[i][j]);                }            }        }        printf("%d\n",f[c]);    }    return 0;}