POJ 1014 Dividing(多重背包 + 倍增优化)

题意:

 求一种划分方案使结果最公平。

思路:

 多重背包,然后把物品分为 2^0, 2^1, ... , 2^k,... 等。

 

#include <iostream>

#include <algorithm>

using namespace std;



const int maxn = 20010 * 3;

int dp[maxn];



void zero1pack(int w, int value, int vol)

{

    for (int v = vol; v >= w; --v)

        dp[v] = max(dp[v], dp[v - w] + value);

}



int main()

{

    int cases = 0;

    while (++cases)

    {

        int arr[10], flag = 0, vol = 0;

        for (int i = 1; i <= 6; ++i)

        {

            scanf("%d", &arr[i]);

            flag |= arr[i];

            vol += arr[i] * i;

        }

        if (flag == 0)

            break ;



        if (vol & 0x01)

        {

            printf("Collection #%d:\nCan't be divided.\n\n", cases);

            continue;

        }



        memset(dp, 0, sizeof(dp));



        for (int i = 1; i <= 6; ++i)

        {

            int v = 1;

            while (v <= arr[i])

            {

                zero1pack(v * i, v * i, vol >> 1);

                arr[i] -= v;

                v <<= 1;

            }

            if (arr[i])

                zero1pack(arr[i] * i, arr[i] * i, vol >> 1);

        }



        if (dp[vol >> 1] == vol >> 1)

            printf("Collection #%d:\nCan be divided.\n\n", cases);

        else

            printf("Collection #%d:\nCan't be divided.\n\n", cases);

    }

    return 0;

}

你可能感兴趣的:(div)