[原创]我的北大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"); } }