/*
poj 1014 Dividing
题意: 分别给出值为1,2,3,4,5,6的数量,把这些分成两份,求能不能分成两份总值相等。
题解: 以前做过把一个数组分成两份,使得两份和差最小。我们用01背包求最大能组成的小于等于sum/2值。
那么这题无非是多重背包,本质是一样的。
*/
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <map>
#include <queue>
using namespace std;
#define LL long long
const int INF = 0x3f3f3f3f;
const int N = 510;
int a[10];
int dp[20010*6];
void slove(int all)
{
// for(int i = 1; i <= 20010*6; i++)
// dp[i] = INF;
memset(dp,0,sizeof(dp));
dp[0] = 1;
for(int i = 1; i <= 6; i++)
{
int num = a[i];
for(int k = 1; k <= num; k *= 2)
{
for(int j = all; j >= k*i; j--)
if(dp[j-k*i] == 1)
dp[j] = 1;
num -= k;
}
for(int j = all; j >= num*i; j--)
if(dp[j-num*i] == 1)
dp[j] = 1;
}
if(dp[all] == 1)
puts("Can be divided.");
else
puts("Can't be divided.");
}
int main()
{
int cas = 1;
while(1)
{
int flag = 0;
int sum = 0;
for(int i = 1 ; i <= 6; i++)
{
cin >> a[i];
sum += a[i]*i;
if(a[i])
flag = 1;
}
if(!flag)
break;
printf("Collection #%d:\n",cas++);
if(sum&1)
puts("Can't be divided.");
else
slove(sum/2);
puts("");
}
return 0;
}
【多重背包】poj 1014 Dividing
最新推荐文章于 2017-05-24 19:52:57 发布