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;
    }
    
  • 相关阅读:
    Web大文件上传断点续传解决方案
    STL 源代码剖析 算法 stl_algo.h -- rotate
    BZOJ 1260 CQOI2007 涂色paint 动态规划
    Shiro学习(总结)
    数组与指针
    Doing Homework again(杭电1789)
    leetCode 75.Sort Colors (颜色排序) 解题思路和方法
    hdu 4786 Fibonacci Tree(最小生成树)
    Havel--Hakimi定理推断可图化 python
    最近小感——一个残疾人写的操作系统
  • 原文地址:https://www.cnblogs.com/cjgjh/p/9499508.html
Copyright © 2011-2022 走看看