/*
Source Code
Problem: 1014 User: xudacheng06
Memory: 284K Time: 0MS
Language: C++ Result: Accepted
Source Code
*/
#include <iostream>
#include <cstdio>
#include <string>
#include <valarray>
using namespace std;
/*
求解思路:
1,设所有大理石的总价值为sum,如果sum%2=1那么不可能等分这些大理石。
2,如果一个人拿走总价值为x的大理石,那么另一个人只能拿走剩余的大理石,对应的价值为(sum-x)。
3,设一个人能够拿走价值为x的大理石,那么标记flg[x] = 1;若再给此人一块价值为i的大理石,那么
此人可以拿起价值为x+i的大理石,即flg[x + i] =1。
4,很显然,flg[0] = 0.
*/
bool flg[20004];
bool canshare(valarray<int>& va,int asum)//asum <= 10000
{
memset(flg,0,20004);
flg[0] = 1;//如果其中一人可以拿走总价值为x的大理石则flg[x] = 1,
int max = 0;//当前能够取走的最大价值
int t;
for(int i = 0; i < va.size(); ++i)
{
if(va[i])
{
for(int j = max; j >= 0; --j)//为什么不从小到大遍历?因为max的值会变化
{
if(flg[j])
{
for(int k = 1; k <= va[i]; ++k)
{
t = j+(i+1)*k;
if(t > asum)continue;//剪枝,如果此时值大于asum,那么此后任何时刻都不可能小于此值了
if(t == asum)return true;
if(t > max)max = t;
flg[t] = 1;
}
}
}
}
}
return flg[asum];
}
int main()
{
//freopen("in.txt","r",stdin);
int k = 1;
valarray<int> va(0,6);
string s;
bool bval;
while(cin>>va[0]>>va[1]>>va[2]>>va[3]>>va[4]>>va[5])
{
valarray<bool> comp = (va == 0);
if(comp.min())break;
cout<<"Collection #"<<k++<<":"<<endl;
bval = false;
{
va %= 16;
int sum = 0;
for(int i = 0; i < 6; ++i)
{
sum += va[i]*(i+1);
}
if(sum%2 == 0)//只有在偶数的情况下才需要进一步计算
bval = canshare(va,sum/2);
}
s = (bval == false)?"Can't be divided.":"Can be divided.";
cout<<s<<endl<<endl;
}
}
pku acm 1014
最新推荐文章于 2016-06-30 18:47:36 发布