标签:循环 之间 out 国际 题目 距离 判断 names 活动
今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:
设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大。
同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子:
有一个数字串:312,当N=3,K=1时会有以下两种分法:
1) 3*12=36
2) 31*2=62
这时,符合题目要求的结果是:31*2=62
现在,请你帮助你的好朋友XZ设计一个程序,求得正确的答案。
4 2 1231
62
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 using namespace std; 5 long long a[30][30],f[30][30];//数组a[i][j]记录从第i位到第j位的数的大小 6 int main() //f[i][j]为前i位数分j个乘号的最大值 7 { 8 int n,k; 9 long long s; 10 scanf("%d%d%lld",&n,&k,&s);//输入位数,乘号的个数,数字串 11 for(int i=n;i>=1;i--) 12 {//如果s是长整型的,数组a也要是长整型的 13 a[i][i]=s%10;//从第i位到第i位就是这个数本身; 14 // cout<<a[i][i]<<endl; 15 s/=10;// 16 } 17 for(int i=2;i<=n;i++) 18 for(int j=i-1;j>=1;j--) 19 a[j][i]=a[j][i-1]*10+a[i][i];//计算每一位到每一位,因为上面已经推出本身到本身,所以任意两位之间的距离都能推出来 20 for(int i=1;i<=n;i++)//特殊处理一下没有乘号的情况 21 f[i][0]=a[1][i];//前i个数分到0个乘号的值就是第1-i这个数本身; 22 for(int i=1;i<=k;i++)//分为k个阶段;即插入k个乘号;每插入一个乘号为一个决策阶段; 23 for(int j=i+1;j<=n;j++)//判断一下最后一个乘号后有几位数(当第i个乘号被分配时,最少有i+1个数, 24 //所以循环从i+1开始) 25 for(int m=i;m<j;m++) 26 f[j][i]=max(f[j][i],f[m][i-1]*a[m+1][j]);//前j个数分配i个乘号取最大值,前m个数分配i-1个乘号的值 27 //再乘以最后一个乘号后的值 28 printf("%lld\n",f[n][k]);//输出n个数分配k个乘号的值 29 return 0; 30 }
标签:循环 之间 out 国际 题目 距离 判断 names 活动
原文地址:http://www.cnblogs.com/zzyh/p/6682097.html