POJ 1014 Dividing

多重背包..看代码吧还是orz

#include <iostream>
using namespace std;

#define LEN 7
#define INIT 0xffffffff
int F[60001];

int max(int x, int y)
{
    return x>y?x:y;
}

void ZeroOnePack(int cost, int weight, int V)
{
    for (int v=V; v>=cost; --v) {
        F[v] = max(F[v], F[v-cost]+weight);
    }
}

void CompletePack(int cost, int weight, int V)
{
    for (int v=cost; v<=V; ++v) {
        F[v] = max(F[v], F[v-cost]+weight);
    }
}

void MultiPack(int cost, int weight, int V, int amount)
{
    if (cost*amount>=V) {
        CompletePack(cost, weight, V);
        return;
    }
    int k = 1;
    while (k<amount) {
        ZeroOnePack(cost*k, weight*k, V);
        amount -= k;
        k *=2;
    }
    ZeroOnePack(cost*amount, weight*amount, V);
}

int main(int argc, char **argv)
{
    int index = 0;
    int num[LEN];
    while (1) {
        ++index;
        int sum = 0;
        int bin = 0;
        for (int i=1; i<LEN; ++i) {
            cin>>num[i];
            sum += i * num[i];
            bin |= num[i];
        }
        if (!bin)
            break;
        if (sum&0x01)
            cout<<"Collection #"<<index<<":\n"<<"Can't be divided."<<endl<<endl;
        else {
            int V = sum>>1;
            F[0] = 0;
            for (int i=1; i<=V; ++i)
                F[i] = INIT;
            for (int i=1; i<LEN; ++i)
                MultiPack(i, i, V, num[i]);
            if(F[V]!=V)
                cout<<"Collection #"<<index<<":\n"<<"Can't be divided."<<endl<<endl;
            else
                cout<<"Collection #"<<index<<":\n"<<"Can be divided."<<endl<<endl;
        }
    }

    return 0;
}
View Code

 

posted @ 2014-04-04 12:05  霖‘  阅读(96)  评论(0编辑  收藏  举报