洛谷NOIP刷题-P1018|洛谷NOIP刷题-P1018 乘积最大

题目描述
今年是国际数学联盟确定的“20002000――世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰9090周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZXZ也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:
设有一个长度为NN的数字串,要求选手使用KK个乘号将它分成K+1K+1个部分,找出一种分法,使得这K+1K+1个部分的乘积能够为最大。
同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子:
有一个数字串:312312, 当N=3,K=1N=3,K=1时会有以下两种分法:
1、3 \times 12=363×12=36 2、31 \times 2=6231×2=62
这时,符合题目要求的结果是: 31 \times 2 = 6231×2=62
现在,请你帮助你的好朋友XZXZ设计一个程序,求得正确的答案。
输入输出格式
输入格式:
程序的输入共有两行:
第一行共有22个自然数N,KN,K(6≤N≤40,1≤K≤66≤N≤40,1≤K≤6)
第二行是一个长度为NN的数字串。
输出格式:
结果显示在屏幕上,相对于输入,应输出所求得的最大乘积(一个自然数)。
【洛谷NOIP刷题-P1018|洛谷NOIP刷题-P1018 乘积最大】输入输出样例
输入样例#1:
4 2
1231
输出样例#1:
62
说明
NOIp2000提高组第二题

#include #include #include #include #include #include #include #include #include typedef long long LL; using namespace std; const int maxn=1005; int n,kk,dp[100][10][maxn],now[maxn],c[maxn]; char a[100]; int cal(int l,int r) { for(int i=now[0]; i>=0; i--) now[i]=0; for(int i=r; i>=l; i--) now[++now[0]]=a[i]-'0'; } void cheng(int a[],int b[]) { for(int i=c[0]; i>=0; i--) c[i]=0; c[0]=a[0]+b[0]; for(int i=1; i<=a[0]; i++) for(int j=1; j<=b[0]; j++) { int tp=c[i+j-1]+a[i]*b[j]; c[i+j-1]=tp%10; c[i+j]+=tp/10; } while(c[c[0]+1]) { ++c[0]; c[c[0]+1]=c[c[0]]/10; c[c[0]]%=10; } while(c[0]!=0&&!c[c[0]]) {c[0]--; } } int cmp(int a[],int b[]) { if(a[0]>b[0]) return 1; else if(a[0]=1; i--) { if(a[i]>b[i]) return 1; else if(a[i]>n>>kk; kk++; scanf("%s",a+1); dp[0][0][0]=dp[0][0][1]=1; for(int i=1; i<=n; i++) { for(int j=1; j<=i; j++) { cal(j,i); for(int k=1; k<=kk; k++) if(dp[j-1][k-1][0]>0){ cheng(now,dp[j-1][k-1]); if(cmp(c,dp[i][k])) { for(int l=0; l<=c[0]; l++) dp[i][k][l]=c[l]; } } } } for(int i=dp[n][kk][0]; i>=1; i--) cout<

    推荐阅读