poj 1014 多重背包

就是判断弹珠是否可以平分,一开始想到了背包模型。一开始转画成了01背包。wa了。那是就一直在纠结物品的cost是什么,假设成了1,后来一直不对,看了题解他们将cost 设定等于就是将cost等同于weight.就是在寻找也可以转化这样想,将所给的标准就是cost,也就是体积的话,问题就转化成了在不考虑价值的情况下。怎么分配可以放满容积为 sum / 2 的背包。

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    using namespace std;
    const int MAXN = 2e5 + 10;
    int c[MAXN];
    int w[MAXN];
    int dp[MAXN * 6];
    bool tag;
    int v;
    void CompeletePack(int w,int c)
    {
        for(int i = c;i <= v;++i)
        {
            dp[i] = max(dp[i],dp[i - c] + w);
            if(dp[i] == v)
            {
                tag = 1;
                return ;
            }
        }
        return ;
    }
    void ZeroOnePack(int w,int c)
    {
        for(int i = v;i >= c;--i)
        {
            dp[i] = max(dp[i],dp[i - c] + w);
            if(dp[i] == v)
            {
                tag = 1;
                return ;
            }
        }
        return ;
    }
    void MultiplePack(int w,int c,int a)
    {
        if(c * a >= v)
        {
            CompeletePack(w,c);
            return ;
        }
        int k = 1;
        while(k < a)
        {
            ZeroOnePack(k * w,k * c);
            if(tag)
                return ;
            k *= 2;
            a -= k;
        }
        ZeroOnePack(w * a,c * a);

    }
    int main()
    {
        int a[10];
        int t = 1;
        while(1)
        {
            int sum = 0,s = 0;
        for(int i = 1;i <= 6;++i)
        {
            cin >> a[i];
            sum += a[i] * i;
            s += a[i];
        }
        v = sum / 2;
        if(!s)
            break;
        else
        {
            cout << "Collection #" << t++ << ':' << endl;
            if(sum % 2)
                cout << "Can't be divided." << endl << endl;
            else
            {
                memset(dp,-1,sizeof(dp));
                dp[0] = 0;
                tag = 0;
               for(int i = 1;i <= 6;++i)
               {
                   MultiplePack(i,i,a[i]);
                   if(tag) break;
               }
               if(tag)
                cout << "Can be divided." << endl << endl;
               else
                cout << "Can't be divided." << endl << endl;

        }   }
        }
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值