zoukankan      html  css  js  c++  java
  • 「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

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

    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:
    ",++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;
    }
    
  • 相关阅读:
    BZOJ 2212/BZOJ 3702
    BZOJ 4761 Cow Navigation
    BZOJ 3209 花神的数论题
    BZOJ 4760 Hoof, Paper, Scissors
    BZOJ 3620 似乎在梦中见过的样子
    BZOJ 3940 Censoring
    BZOJ 3942 Censoring
    BZOJ 3571 画框
    BZOJ 1937 最小生成树
    BZOJ 1058 报表统计
  • 原文地址:https://www.cnblogs.com/cjgjh/p/9499508.html
Copyright © 2011-2022 走看看