HDU 1059 Dividing——多重背包+二进制优化
原创
©著作权归作者所有:来自51CTO博客作者软糖酱八号机的原创作品,请联系作者获取转载授权,否则将追究法律责任
题意:6个物品,价值为1 2 3 4 5 6,每次告诉你每个物品有多少个,问你是否能选出一些物品,使得这些物品的价值为所有物品总价值的一半
思路:直接多重背包,加个二进制优化防超时
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1e6 + 10;
int kase = 0, a[10], b[maxn];
bool dp[maxn];
int main() {
while (~scanf("%d %d %d %d %d %d", &a[1],&a[2],&a[3],&a[4],&a[5],&a[6])) {
if (a[1]+a[2]+a[3]+a[4]+a[5]+a[6] == 0) break;
int sum = 0;
for (int i = 1; i <= 6; i++) sum += a[i]*i;
printf("Collection #%d:\n", ++kase);
if (sum & 1) {
printf("Can't be divided.\n\n"); continue;
}
int cnt = 0;
for (int i = 1; i <= 6; i++) {
int j = 0;
while (a[i] >= (1<<j)) {
b[++cnt] = (1<<j)*i;
a[i] -= (1<<j);
j++;
}
if (a[i] > 0) {
b[++cnt] = a[i]*i;
}
}
int mid = sum / 2;
for (int i = 0; i <= mid; i++) dp[i] = false;
dp[0] = true;
for (int i = 1; i <= cnt; i++) {
for (int j = mid; j >= b[i]; j--) {
if (dp[j-b[i]]) dp[j] = true;
}
}
if (dp[mid]) printf("Can be divided.\n");
else printf("Can't be divided.\n");
printf("\n");
}
return 0;
}