[原创]我的北大ACM POJ 1014解答

[原创]我的北大ACM POJ 1014解答

动态规划DP的题,没看提示之前还真不知怎么写。。。

Source Code

Problem: 1014 User: absolute
Memory: 256K Time: 16MS
Language: C++ Result: Accepted
  • Source Code
    #include <stdio.h>
    void POJ1014();
    int main()
    {
    	POJ1014();
    	return 0;
    }
    //查找是否可以通过组合凑出价值为sum
    bool Divided(int* nums,int sum)
    {
    	//hasvalue存储通过组合是否可以达到相应价值
    	bool hasvalue[60001]={0};
    	hasvalue[0] = true;
    	//maxsum存储目前组合达到的最大价值
    	int i,maxsum=0,temp,j,k;
            //dp法分6个阶段,每个阶段都使用上一段可能凑出的价值加上当前阶段可能的价值
             //最后即可得出所有可能凑出的价值
    	for(i=1;i<7;i++)
    	{
    		if(nums[i-1]!=0)
    		{
    			for(j=maxsum;j>=0;j--)
    			{
    				if(hasvalue[j])
    				{
    				        temp = j;
                                            //这个很重要,如果首个已经达到了,则后面的可以不用判断
                                                 //因为可以从该达到的值加temp达到,而由于该值已经达到,说明已经判断过
                                                 //它后面加temp的值
                                                 // value+temp, value+temp+temp->[value+temp],[value+temp]+temp
                                            if((temp+i>sum)||hasvalue[temp+i])
                                                continue;
    					for(k=0;k<nums[i-1];k++)
    					{
    						temp += i;
                                                    if(temp>sum)
                                                        break;
    						hasvalue[temp] = true;
    						if(temp==sum)
    							return true;
    					}
    					if(temp>maxsum)
    						maxsum=temp;
    					if(maxsum>sum)
    						maxsum=sum;
                                     }
    			}
    		}
    	}
    	if(hasvalue[sum])
    		return true;
    	else
    		return false;
    }
    void POJ1014()
    {
    	int ncase=0;
    	while(1)
    	{
    		ncase++;
    		int sum=0,i;
    		int nums[6]={0};
                    bool alleven = true;
    		for(i=0;i<6;i++)
    		{
    			scanf("%d",nums+i);
    			sum += nums[i]*(i+1);
                            if(nums[i]%2!=0)
                                alleven=false;
    		}
    		if(sum==0)
    			return;
    		printf("Collection #%d:\n",ncase);
                   //所有价值的都是偶数个则可以分
                     if(alleven)
                   {
                       printf("Can be divided.\n");
                       continue;
                   }
                    //价值相加总和为奇数则不可分
    		if(sum%2!=0)
    			printf("Can't be divided.\n");
    		else
    		{
    			if(Divided(nums,sum/2))
    			{
    				printf("Can be divided.\n");
    			}
    			else
    				printf("Can't be divided.\n");
    		}
                    printf("\n");
    
    	}
    }

posted on 2009-04-18 14:53  absolute  阅读(610)  评论(0编辑  收藏  举报

导航