题意:价值分别为1,2,3,4,5,6的物品个数分别为a[1],a[2],a[3],a[4],a[5],a[6],问能不能分成两堆价值相等的。
题解:分成价值相等的两堆,价值是多少?一半,然后就能够用背包看能不能凑出来。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#include <ctype.h>
#include <limits.h>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <stack>
#include <set>
#include <bitset>
#define CLR(a) memset(a, 0, sizeof(a))
#define REP(i, a, b) for(int i = a;i < b;i++)
#define REP_D(i, a, b) for(int i = a;i <= b;i++)
typedef long long ll;
using namespace std;
const int maxn = 2e5 + 100;
int dp[maxn], c[20];
int tot;
void getDp()
{
memset(dp, -1, sizeof(dp));
dp[0] = 0;
REP_D(i, 1, 6)
{
REP_D(j, 0, tot)
{
if(dp[j]!=-1)//这个是必须的,既然代表了当前的含义,就要更新
{
dp[j] = 0;
}
else
{
if(j >=i && dp[j - i]!=-1&&dp[j-i]+1<=c[i])
{
dp[j] = dp[j-i]+1;
}
}
}
}
}
int flag;
void solve()
{
getDp();
if(dp[tot]!=-1)
{
flag = 1;
}
else
{
flag = 0;
}
}
int main()
{
// freopen("1Ain.txt", "r", stdin);
//freopen("1Aout.txt", "w", stdout);
int ncase = 0;
while(scanf("%d%d%d%d%d%d", &c[1], &c[2], &c[3], &c[4], &c[5], &c[6]) != EOF)
{
if(!c[1]&&!c[2]&&!c[3]&&!c[4]&&!c[5]&&!c[6])
{
break;
}
else
{
ncase++;
printf("Collection #%d:\n", ncase);
int tmp = 0;
REP_D(i, 1, 6)
{
tmp += i*c[i];
}
if(tmp%2==1)
{
flag = 0;
}
else
{
tot = tmp/2;
solve();
}
if(flag)
{
printf("Can be divided.\n");
}
else
{
printf("Can't be divided.\n");
}
printf("\n");
}
}
return 0;
}