hdu1059

题意:把价值为1,2,3,4,5,6的宝石平均分成两份,不能切割,有没有办法分开。

分析:多重背包。之前直接用01背包的方法做78ms,然后想试试用二进制优化,看看能跑多少。发现,用二进制反而变421ms。

#include <cstdio>

int main()
{
    int marble[7],p = 1;
    bool knapsack[120000];
    while(true)
    {
        int sum = 0;
        for(int i = 1;i <= 6;i++)
        {
            scanf("%d",&marble[i]);
            sum += i * marble[i];
        }
        if(sum == 0)
            break;
        printf("Collection #%d:\n",p++);
        if(sum % 2 != 0)
        {
            printf("Can't be divided.\n\n");
            continue;
        }
        sum /= 2;
        for(int i = sum;i > 0;i--)
            knapsack[i] = false;
        knapsack[0] = true;
        int aux[30],s;
        for(int i = 1;i <= 6;i++)
        {
            //二进制思想拆分物品
            for(s = 0;(1 << s) <= marble[i];s++)
            {
                aux[s] = 1 << s;
                marble[i] -= aux[s];
            }
            if(marble[i] != 0)
                aux[s++] = marble[i];
            for(int j = 0;j < s;j++)
            {
                int temp = aux[j] * i;
                for(int k = sum;k >= temp;k--)
                    knapsack[k] = knapsack[k - temp] || knapsack[k];
            }
        }
        if(knapsack[sum])
            printf("Can be divided.\n\n");
        else
            printf("Can't be divided.\n\n");
    }
}
原文地址:https://www.cnblogs.com/ZShogg/p/3070721.html