HDU 1059 Dividing(多重背包 , 二进制优化形成01背包)

来源:互联网 发布:支付宝和淘宝怎么解绑 编辑:程序博客网 时间:2024/06/05 19:25
  • 题目链接: 1059 Dividing
  • 题意: 有6个物品,一个物品的价值=该物品的编号i (1-6),给定每个物品的数量,问,是否能将所有物品分成价值相等的两堆?
  • 解法: 多重背包,将价值当作背包承受量,物品数量当作价值.
#include<stdio.h>#include<string.h>int a[7];int f[120005];int v,k;void ZeroOnePack(int cost,int weight)//cost 为费用, weight 为价值 {    for(int i=v;i>=cost;i--)       if(f[i-cost]+weight>f[i]) f[i]=f[i-cost]+weight;}    void CompletePack(int cost,int weight){    for(int i=cost;i<=v;i++)        if(f[i-cost]+weight>f[i]) f[i]=f[i-cost]+weight;}         void MultiplePack(int cost ,int weight,int amount){    if(cost*amount>=v) CompletePack(cost,weight);    else    {        for(int k=1;k<amount;)        {            ZeroOnePack(k*cost,k*weight);            amount-=k;            k<<=1;        }            ZeroOnePack(amount*cost,amount*weight);    }    }    int main(){    int tol;    int iCase=0;    while(1)    {        iCase++;        tol=0;        for(int i=1;i<7;i++)        {            scanf("%d",&a[i]);            tol+=a[i]*i;//总价值数         }          if(tol==0) break;        if(tol%2==1)        {            printf("Collection #%d:\nCan't be divided.\n\n",iCase);            continue;        }              else        {            v=tol/2;            memset(f,0,sizeof(f));            for(int i=1;i<7;i++)              MultiplePack(i,i,a[i]);            if(f[v]==v)               printf("Collection #%d:\nCan be divided.\n\n",iCase);            else printf("Collection #%d:\nCan't be divided.\n\n",iCase);        }        }        return 0;    }    
阅读全文
0 0
原创粉丝点击