POJ 1014 Dividing

POJ 1014 Dividing

题意:

多重背包问题,给出若干物品,求是否能分成价值相同的两堆

思考:

求出总和 \(sum\) 之后,如果 \(sum\) 是奇数则一定不可能,然后如果我们能凑出 \(sum / 2\) 的话,那就可以平分,这里就变成了多重背包问题了。

实现:

#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 6e4 + 5;
int f[N];
int a[10], goods[N];
int main()
{
    int lun = 1;
    while (scanf("%d", &a[1]) != EOF)
    {
        int sum = a[1] * 1;
        for (int i = 2; i <= 6; i++)
        {
            scanf("%d", &a[i]);
            sum += a[i] * i;
        }
        if (sum == 0)
        {
            printf("\n");
            break;
        }
        int m = sum / 2;
        for (int i = 0; i <= m; i++)
            f[i] = 0;

        for (int i = 1; i <= 6; i++)
        {
            int v = i, s = a[i];
            int cnt = 1;
            for (int j = 1; j <= s; j *= 2)
            {
                goods[cnt++] = v * j;
                s -= j;
            }
            if (s > 0)
                goods[cnt++] = s * v;

            for (int j = 1; j < cnt; j++)
            {
                for (int k = m; k >= goods[j]; k--)
                {
                    f[k] = max(f[k], f[k - goods[j]] + goods[j]);
                }
            }
        }
        printf("Collection #%d:\n", lun++);
        if (f[m] == m && sum % 2 == 0)
            printf("Can be divided.\n");
        else
            printf("Can't be divided.\n");
        printf("\n");
    }
    return 0;
}
posted @ 2022-12-24 17:55  zxr000  阅读(20)  评论(0)    收藏  举报