pku acm 1014

来源:互联网 发布:网络数码显微互动教室 编辑:程序博客网 时间:2024/04/28 19:50
/*Source CodeProblem: 1014User: xudacheng06Memory: 284KTime: 0MSLanguage: 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;    }    }