8.20.3 Dividing

任务描述

本关任务:MarshaBill收藏了一批大理石。他们想要在他们之间分割收藏的大理石,使得他俩拥有相等的大理石份额。如果所有的大理石的价值相同,那么就很容易,因为他们只要将他们的收藏一分为二就可以了。但不幸的是,一些大理石比较大,或者比其他的大理石更漂亮。所以,MarshaBill开始给每块大理石赋一个值,一个在16之间的自然数。现在他们想平分这些大理石,使每个人得到总价值相同。但不幸的是,他们意识到,以这种方式划分大理石是不可能的(即使所有的大理石的总价值是偶数)。例如,如果有一块大理石的价值为1,一块大理石的价值为3,两块大理石的价值为4,那么它们不可能被分成具有相等的价值的大理石集合。因此,他们要求您写一个程序,确定是否有一个公平划分大理石的方法。

编程要求

根据提示,在右侧编辑器补充代码。

测试说明

输入描述: 在输入的每一行描述一个要被分割的大理石的集合。行中包含六个非负整数n1​,...,n6​,其中ni​是价值为i的大理石的数目。所以,从上述的例子可以用行"1 0 1 2 0 0"描述。大理石价值的总数不超过20000。 输入文件的最后一行是"0 0 0 0 0 0";程序不必处理这一行。

输出描述: 对于每个集合,输出"Collection #k:",其中k是测试用例的编号,然后输出"Can be divided.""Can't be divided."。 在每个测试用例后,输出一空行。

平台会对你编写的代码进行测试:

测试输入: 1 0 1 2 0 0 1 0 0 0 1 1 0 0 0 0 0 0 预期输出: Collection #1: Can't be divided.

Collection #2: Can be divided.

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e3+10;
const ll mod = 1e9+7;
const int inf = 0x7FFFFFFF;

int a[7];
int dp[1000000];



void solve(){
    
    int sum = 0;
    for(int i = 1;i <= 6;i++){
        sum += i*a[i];
    }
    if(sum%2){
        printf("Can't be divided.\n");
        return;
    }
    int n = sum/2;
    
    for(int i = 0;i <= n;i++){
        dp[i] = -inf;
    }
    dp[0] = 0;
    for(int i = 1;i <= 6;i++){
        int num = min(a[i],n/i);
        for(int k = 1;num > 0;k <<= 1){
            if(k > num) k = num;
            num -= k;
            for(int j = n;j >= i*k;j--){
                dp[j] = max(dp[j],dp[j-i*k]+i*k);
            }
        }
    }
    if(dp[n] == n){
        printf("Can be divided.\n");
    }else printf("Can't be divided.\n");
}
int main(){
    int cnt = 1;
    while(scanf("%d%d%d%d%d%d",&a[1],&a[2],&a[3],&a[4],&a[5],&a[6])&&a[1]+a[2]+a[3]+a[4]+a[5]+a[6]){
        printf("Collection #%d:\n",cnt++);
        solve();
        cout<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值