【多重背包】HDU1059Dividing

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1059

这个题目据说是有两种方法可以过的。

我的第一反应就是多重背包(原理我就不解释),先看AC代码;

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=500005;
int n,m;
int dp[N];
int data[7];
void ZeroOnePack(int v,int w)
{
    for(int i=m;i>=v;i--)
        dp[i]=max(dp[i-v]+w,dp[i]);
}
void CompletePack(int v,int w)
{
    for(int i=v;i<=m;i++)
        dp[i]=max(dp[i],dp[i-v]+w);
}
void MultiPack(int v,int w,int cnt)
{
    if(v*cnt>=m){
        CompletePack(v,w);
        return;
    }
    for(int i=1;i<cnt;i*=2){
        ZeroOnePack(i*v,i*w);
        cnt-=i;
    }
    ZeroOnePack(cnt*v,cnt*w);
}
int main()
{
    int Case=1;
    while(scanf("%d",&data[1])!=EOF){
        for(int i=2;i<=6;i++) scanf("%d",&data[i]);
        bool out=true;
        int sum=0;
        for(int i=1;i<=6;i++){
            sum+=data[i]*i;
            if(data[i]) out=false;
        }
        if(out) break;
        m=sum/2;
        printf("Collection #%d:\n",Case++);
        if(sum&1){
            printf("Can't be divided.\n");
            printf("\n");
            continue;
        }
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=6;i++)
            if(data[i]) MultiPack(i,i,data[i]);
        if(dp[m]==m) printf("Can be divided.\n");
        else printf("Can't be divided.\n");
        printf("\n");
    }
    return 0;
}


 

你可能感兴趣的:(hdu1059)