一、问题描述
二、解答思路
使用动态规划。定义一个数组b[60005]。b[i]表示是否可以分成i和sum-i两份。显然b[0]=true。如果b[sum/2]==true,则说明可以分割。如果b[k]=true,则b[k+i]=true,i为石子价值。
三、代码
#include<iostream> #include<string.h> using namespace std; int num[7]; bool b[60005];
int main() { int i,j,k; int sum ; int c=1; bool first=true; int half; bool flag;
while(scanf("%d%d%d%d%d%d",&num[1],&num[2],&num[3],&num[4],&num[5],&num[6])!=EOF) { if(num[1]==0 && num[2]==0 && num[3]==0 && num[4]==0 && num[5]==0 && num[6]==0) break;
//for(i=1;i<=6;++i)
//num[i]=num[i]%60;
flag=false; memset(b,0,sizeof(b)); b[0]=true; if(first ==false) { printf("\n"); } else first=false; printf("Collection #%d:\n",c); c++; sum=0; for(i=1;i<=6;++i) sum+=(i*num[i]); if(sum % 2 ==1) { printf("Can't be divided.\n"); continue; } half=sum/2; int Max=0; for(i=1;i<=6;++i) { if(b[half]) break; for(j=1;j<=num[i];++j) { if(b[half-i]) { b[half]=true; printf("Can be divided.\n"); break; } for(k=Max;k>=0;k--) { if(b[k] && k+i<=half) { if(b[k+i]) break; else b[k+i]=true; if(k+i > Max) Max=k+i; } } } } if(b[half]==false) printf("Can't be divided.\n"); } return 0; }
|
阅读(1534) | 评论(0) | 转发(0) |