hdu 1059 Dividing bitset 多重背包

bitset做法

#include <bits/stdc++.h>
#define PI acos(-1.0)
#define mem(a,b) memset((a),b,sizeof(a))
#define TS printf("!!!\n")
#define pb push_back
//std::ios::sync_with_stdio(false);
using namespace std;
//priority_queue<int,vector<int>,greater<int>> que;
const double EPS = 1.0e-8;
typedef pair<int, int> pairint;
typedef long long ll;
typedef unsigned long long ull;
const int  maxn = 2e5 + 100;
const int  maxm = 300;
//next_permutation
//priority_queue<int, vector<int>, greater<int>> que;
int num[10];
bitset<120005>f;
int main()
{
        //freopen("bonuses.in", "r", stdin);
        //freopen("out.txt", "w", stdout);
        int t = 0;
        int sum = 0;
        //cin >> t;
        while (cin >> num[1] >> num[2] >> num[3] >> num[4] >> num[5] >> num[6] && (num[1] + num[2] + num[3] + num[4] + num[5] + num[6]))
        {
                t++;
                cout<<"Collection #"<<t<<":"<<endl;
                sum = 0;
                f.reset();
                f[0] = 1;
                for (int i = 1; i <= 6; i++)
                {
                        sum += num[i] * i;
                }
                if (sum % 2)
                {
                        cout << "Can't be divided." << endl;
                }
                else
                {
                        sum /= 2;
                        for (int i = 1; i <= 6; i++)
                        {
                                int g = 1;
                                int v = i;
                                int tot = num[i];
                                while (tot)
                                {
                                        f |= f << v;
                                        tot -= g;
                                        g = min(g * 2, tot);
                                        v = g * i;
                                }
                        }
                        if (f[sum])
                        {
                                cout << "Can be divided." << endl;
                        }
                        else
                        {
                                cout << "Can't be divided." << endl;
                        }
                        //for(int i=1;i<=sum;i++)
                        //cout<<f[i]<<" ";
                        //cout<<endl;
                }
                cout<<endl;
        }

}

多重板子做法

//多重背包
//HDU 1059
//题意:价值分别为1,2,3,4,5,6的物品的个数分别为 a[1],a[2],````a[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;    
}

 

posted @ 2017-10-02 14:18  Aragaki  阅读(178)  评论(0编辑  收藏  举报