说明
过年啦!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;
}