pku acm 1014

/*
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;
    	}
    }



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章