1、http://acm.hdu.edu.cn/showproblem.php?pid=1059
处理大数据,模余最小公倍数
2、题目大意:
Marsha 和Bill收集了很多 弹球,现在他们想把这些弹球分开,要求两个人分的一样多,如果所有的弹球都有相同的价值,那么分将很容易,一人得到一半即可,但是不幸的是,有些弹球很大,有些比别的漂亮,现在他们给每个弹球都估算了一个价值,价值分别是1、2、3、4、5、6,现在他们想把这些弹球分成两部分,要求两人的价值相同,同时他们意识到分开很难,因为如果是奇数将分不开,即便是偶数,也不一定能分开,例如,有一个价值为1的,一个价值为3的,两个价值为4的,就不能分成相等的两部分,因此需要你写一个程序判断能不能将这些弹球分成价值相等的两部分
输入:每行包括6个非负数的整数,n1, n2, ..., n6,ni代表价值为i的弹球有ni个,个数可能最大达到20000
输出:
每个样例输出``Collection #k:'',k是第几个样例数,然后输出``Can be divided.'' or ``Can't be divided.''.
3、题目:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10834 Accepted Submission(s): 3035
1 0 1 2 0 0 1 0 0 0 1 1 0 0 0 0 0 0
Collection #1: Can't be divided. Collection #2: Can be divided.
4、代码:
#include<stdio.h> #include<string.h> #include<algorithm> #define minn -9999999 using namespace std; int v[120005]; int dp[420005]; int main() { int a[10],cas=0; while(1) { cas++; int flag=0,sum=0; memset(v,0,sizeof(v)); for(int i=1; i<=6; i++) { scanf("%d",&a[i]); a[i]=a[i]%60;//%最小公倍数 sum+=a[i]*i; } for(int i=1; i<=sum/2+1; i++) dp[i]=minn; dp[0]=0; if(sum%2!=0) flag=1; if(a[1]==0&&a[2]==0&&a[3]==0&&a[4]==0&&a[5]==0&&a[6]==0) break; int k=1; for(int i=1; i<=6; i++) { for(int j=1; j<=a[i]; j=j*2) { v[k++]=i*j; a[i]-=j; } if(a[i]>0) { v[k++]=a[i]*i; } } for(int i=1; i<=k; i++) { for(int j=sum/2; j>=0; j--) { if(j>=v[i]) dp[j]=max(dp[j],dp[j-v[i]]+v[i]); } } printf("Collection #%d:\n",cas); if(dp[sum/2]<0||flag==1) { printf("Can't be divided.\n"); printf("\n"); } else { printf("Can be divided.\n"); printf("\n"); } } return 0; } /* 1 0 1 2 0 0 1 0 0 0 1 1 0 0 0 0 0 0 */