『CJOJ2736』『POJ1014』大理石分割

Problem

Description

Marsha和Bill收藏了一些大理石。他们想要把这些大理石平均分配给两个人。如果大理石的价值一样,这将很容易做到,因为他们可以简单的对半分。不幸的是,一些大理石比其他的更大或者更漂亮。因此Marsha和Bill给每个大理石都规定了一个价值,它是一个1~6之间的自然数。现在他们想要把这些大理石分成两部分,每部分的价值之和相等。但他们很快意识到有可能不存在这样的分法(即使大理石的价值之和是偶数)。例如,如果大理石的价值分别是1,1,3,4,4,就不可能被分为总价值相等的两部分。因此,他们请你写一个程序,判断是否存在公平的分法。

Input

输入包含多组数据。

每组数据由1行,包含6个正整数n1~n6,其中ni是价值为i的大理石数量。因此题目描述中的例子可以被表示为"1 0 1 2 0 0"。大理石的总数不超过20000.

Output

对第k组数据,输出一行"Collection #k:",再输出一行"Can be divided."或"Can't be divided.",然后再输出一个空行。

Sample Input

1 0 1 2 0 0

1 0 0 0 1 1

0 0 0 0 0 0

Sample Output

Collection #1:
Can't be divided.

Collection #2:
Can be divided.

Solution

思路

其实考场的时候我对于我自己的想法十分的窒息,我竟然用贪心?很鬼畜啊,这果然不是我...
然后这道题目显然一眼看得出,是多重背包,然后看到背包就知道不用二进制肯定过不了,然后果断写上二进制,然后就切了.

Remind

特别注意多组数据注意清零数组...(我最近的操作真是令人绝望)

扫描二维码关注公众号,回复: 2846992 查看本文章

Code

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<iostream>
using namespace std;
#define ll long long
#define re register
inline int gi(){
    int sum=0,f=1;char ch=getchar();
    while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    return sum*f;
}
int n,a[7],dp[1000010],t[1000010];
int main(){
    n=6;int k=0;
    while(1){
        memset(dp,0,sizeof(dp));
        int sum=0;
        for(re int i=1;i<=n;i++){a[i]=gi();sum+=i*a[i];}
        if(sum==0)break;
        printf("Collection #%d:\n",++k);
        if(sum%2)puts("Can't be divided.");
        else{
            int count=0;
            for(re int i=1;i<=n;i++){
                int k=1,weight=a[i];
                while(k<=weight){
                    t[++count]=i*k;
                    weight-=k;k<<=1;
                }
                t[++count]=i*weight;
            }
            sum/=2;
            for(re int i=1;i<=count;i++)
                for(re int j=sum;j>=t[i];j--)
                    dp[j]=max(dp[j],dp[j-t[i]]+t[i]);
            if(dp[sum]==sum)puts("Can be divided.");
            else puts("Can't be divided.");
        }
        puts("");
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/cjgjh/p/9499508.html