标签:
题目:有一些石头,每块石头有一个价值价值(1~6中的一个整数),现在把石头分成两组,
问能否分成价值和相同的两组。
分析:dp,01背包。背包容量为总和的一半,判断能否放满即可。
说明:数据较大,使用二进制拆分╮(╯▽╰)╭。
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int f[60001],c[6],w[6] = {1,2,3,4,5,6};
int p[60001];
int main()
{
int t = 1;
while (scanf("%d%d%d%d%d%d",&c[0],&c[1],&c[2],&c[3],&c[4],&c[5])) {
int sum = 0;
for (int i = 0 ; i < 6 ; ++ i)
sum += c[i]*w[i];
if (sum == 0) break;
//二进制拆分
int count = 0;
for (int i = 0 ; i < 6 ; ++ i) {
int k = 1,cc = c[i];
while (k < cc) {
p[count ++] = k*w[i];
cc -= k;
k <<= 1;
}
if (cc) p[count ++] = cc*w[i];
}
printf("Collection #%d:\n",t ++);
if (sum%2) printf("Can't be divided.\n\n");
else {
int m = sum/2;
memset(f, 0, sizeof(f));
f[0] = 1;
for (int i = 0 ; i < count ; ++ i)
for (int v = m ; v >= p[i] ; -- v)
if (f[v-p[i]])
f[v] = 1;
if (!f[m])
printf("Can't be divided.\n\n");
else printf("Can be divided.\n\n");
}
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/mobius_strip/article/details/44033851