hdu 1059

多重背包。。。


所有的背包,感觉都以01背包为基础,所以。。不懂多用数据,多模拟。。就懂了


1.未经优化版本,先理解这个,二进制只是把这个改进了一下而已

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

int main()
{
    int f[12005];
    int num[7],v;
    freopen("in.txt","r",stdin);
    for(int t=1;;t++)
    {
        memset(f,0,sizeof(f));
        v=0;
        for(int i=1;i<=6;i++)
        {
            scanf("%d",&num[i]);
            v+=num[i]*i;

        }
        if(!v)break;
        printf("Collection #%d:\n",t);
        if(v%2)printf("Can't be divided.\n");
        else
        {
            v=v/2;
            for(int i=1;i<=6;i++)
            {
                for(int j=1;j<=num[i];j++)
                {
                    for(int k=v;k>=i;k--)
                    {
                        f[k]=f[k]>f[k-i]+i?f[k]:f[k-i]+i;
                    }
                }
            }

            if(f[v]==v)printf("Can be divided.\n\n");
            else printf("Can't be divided.\n\n");
        }
    }
    return 0;
}


背包九讲虽然些的好,毕竟纸上谈兵,感觉网上有的带表格,一步步走数据的方法结合起来学的更透彻


AC:

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int tot;
int f[120005],a[7];

void ZeroOnePack(int cost,int weight)
{
    for(int v=tot;v>=cost;v--)
    {
        f[v]=f[v]>f[v-cost]+weight?f[v]:f[v-cost]+weight;
    }
}

void CompletePack(int cost,int weight)
{
    for(int v=cost;v<=tot;v++)
    {
        f[v]=f[v]>f[v-cost]+weight?f[v]:f[v-cost]+weight;
    }
}

void MultiplePack(int cost,int weight,int amount)
{
    if(cost*amount>=tot)CompletePack(cost,weight);
    else
    {
        for(int k=1;k<amount;k=k<<1)
        {
            ZeroOnePack(k*cost,k*weight);
            amount=amount-k;
        }
        ZeroOnePack(amount*cost,amount*weight);
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    for(int t=1;;t++)
    {

        tot=0;
        for(int i=1;i<=6;i++)
        {
            scanf("%d",&a[i]);
            tot+=a[i]*i;
        }
        if(!tot)break;
        printf("Collection #%d:\n",t);
        if(tot%2)printf("Can't be divided.\n\n");
        else
        {
            tot=tot/2;memset(f,0,sizeof(f));
            for(int i=1;i<=6;i++)
            {
                MultiplePack(i,i,a[i]);
            }
            if(f[tot]==tot)printf("Can be divided.\n\n");
            else printf("Can't be divided.\n\n");
        }

    }

    return 0;
}


你可能感兴趣的:(hdu 1059)