#C. wll 的糖果分配

该问题是一个关于分配糖果的问题,要求将66种不同美味度的糖果在弟弟和妹妹间平均分配,每种糖果数量不同。通过01背包算法来检查当前糖果是否能平均分配,若不能,则输出Cantbedivided.,反之则输出Canbedivided.。

说明

过年啦!wll 带着好多好多的糖果回到家里,打算分给弟弟妹妹们

她一共带回了 66 种不同的糖果,第 ii 种糖果的美味度为 ii,共有 a_iai

但是弟弟们和妹妹们不想在一起玩,他们想分别拿走糖果,各自玩耍

那么如何分糖果成为了一个问题, wll 希望弟弟们和妹妹们拿到的糖果美味度之和是一样的

现在她想知道她手里的糖果能不能这样分?如果不够她现在立刻去买!

输入格式

输入第一行包含 66 个整数 a_iai,分别表示每种糖果的数量

对于 50\%50% 的数据保证:0 \leq a_i \leq 100≤ai≤10

对于 100\%100% 的数据保证:0 \leq a_i \leq 30000≤ai≤3000

输出格式

输出一行,如果现在 wll 手里的糖果能够平分给弟弟们和妹妹们,则输出 `Can be divided.`,如果不能则输出 `Can't be divided.`

样例

输入数据 1

1 2 3 4 5 6

输出数据 1

Can't be divided.


思路1

先将分组背包的个数拆开变成01背包,在将01背包思路变一下,背包容量变成整个数组的累加和/2,最后判断整个数组的累加和是否等于2 * dp[整个数组的累加和 / 2],等于则输出can,否则输出can't。


标程1

#include <bits/stdc++.h>
using namespace std;
int n,sum,dp[10000001],a[10000001];
int main()
{
  for(int i = 0; i < 6; i++)
  {
    int t;
    scanf("%lld",&t);
    for(int j = 0; j < t; j++) a[n++] = (i + 1);
    sum += (i + 1) * t;
  }
  if(sum % 2 == 1)
  {
    printf("Can't be divided.");
    return 0;
  }
  for(int i = 1; i <= n; i++)
    for(int j = sum / 2; j >= 0; j--)
      if(j >= a[i - 1]) dp[j] = max(dp[j], dp[j - a[i - 1]] + a[i - 1]);
      else dp[j] = dp[j];
  bool flag = (sum - 2 * dp[sum / 2] == 0);
  if(flag) printf("Can be divided.");
  else printf("Can't be divided.");
  return 0;
}

思路2


标程

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[7][210010], a[10];
int main() {
int sum = 0;
for (int i = 1; i <= 6; i++) {
cin >> a[i];
sum += a[i] * i;
}
if (sum % 2 == 1) {
cout << "Can't be divided." << endl;
return 0;
}
sum /= 2;
dp[0][0] = 1;
for (int i = 1; i <= 6; i++) {
for (int j = 0; j <= sum; j++) {
for (int k = 0; k <= a[i]; k++) {
if (j >= k * i) {
dp[i][j] |= dp[i - 1][j - k * i];
}
}
}
}
if (dp[6][sum]) {
cout << "Can be divided." << endl;
return 0;
}
cout << "Can't be divided." << endl;
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值