HDU 1059 - Dividing

题目描述

Dividing

解法:多重背包

首先确定的是这道题应该往多重背包上靠,但是有不同于多重背包:没有代价(volume)这一项。所以,我们在多重背包二进制优化分解后,主要找是否存在一种分配策略使得一个人能得到的商品价值等于总价值的一半,如果存在则说明可以划分

#include <iostream>
#include <string.h>
#include <algorithm>

using namespace std;


int main()
{
    int marbles[7], w[23000], dp[50000], sum, a, cnt = 0;
    while(scanf("%d%d%d%d%d%d", &marbles[1], &marbles[2], &marbles[3], &marbles[4], &marbles[5], &marbles[6])&& marbles[1]+marbles[2]+marbles[3]+marbles[4]+marbles[5]+marbles[6])
    {
        int k = 1, sum = 0;
        memset(dp, 0, sizeof(dp));
        for(int i=1;i<=6;i++)
        {
            sum += marbles[i]*i;
            for(int j=1;j<=marbles[i];j<<=1)
            {
                w[k++] = j*i; // 物品价值
                marbles[i] -= j;
            }
            if(marbles[i]>0) w[k++] = marbles[i]*i;
        }

        a = sum / 2;
        for(int i=1;i<k;i++)
        {
            for(int j=a;j>=w[i];j--)
                dp[j] = max(dp[j], dp[j-w[i]]+w[i]);
        }
        printf("Collection #%d:\n", ++cnt);
        if(dp[a]==sum-a) printf("Can be divided.\n\n");
        else printf("Can't be divided.\n\n");
    }
    return 0;
}
发布了152 篇原创文章 · 获赞 22 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_38204302/article/details/105210119