C. 数字串划分
时间限制(普通/Java) :
1000 MS/ 3000 MS 运行内存限制 : 65536 KByte
总提交 : 25 测试通过 : 12
总提交 : 25 测试通过 : 12
比赛描述
给你连续的N个数字符,在其中插入K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大。
输入
程序的输入共有两行:
第一行是2个正整数N,K(6≤N≤40,1≤K≤6)
第二行是N个连续的数字符。
输出
输出所求得的最大乘积(一个自然数)。
样例输入
4 2
1231
样例输出
62
提示
1*2*31=62
题目来源
BYK
/* Internet 7MS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <limits.h>
int N,K; //N为数字串长度,K为乘号个数
char ch[45]; //数字串
void calBSum(){
int F[45],i,iSum,itmpK,itmpN;
char ctemp[45];
iSum=0;
for (i=1;i<=N-K;i++){ //为零个乘号积
iSum=ch[i]-'0'+iSum*10;
F[i]=iSum;
}
for (itmpK=1;itmpK<=K;itmpK++){
for (itmpN=N-K+itmpK;itmpN>=itmpK+1;itmpN--){
F[itmpN]=INT_MIN;
for (i=itmpK;i<=itmpN-1;i++){
memcpy(ctemp,ch+i+1,itmpN-i);
ctemp[itmpN-i]=0;
if (F[i]*atoi(ctemp)>F[itmpN]){
F[itmpN]=F[i]*atoi(ctemp);
}
}
}
}
printf("%d\n",F[N]);
}
int main(){
int i;
scanf("%d%d",&N,&K);
getchar();
for (i=1;i<=N;i++){
scanf("%c",&ch[i]);
}
calBSum();
}
*/
// 3MS
#include<iostream>
#define MAX_N 40
#define MAX_K 6
int a[MAX_N+1][MAX_K+1];
int dp[MAX_N+1][MAX_K+1];
int num[MAX_N+1][MAX_N+1];
char c[MAX_N+2];
int main(){
// freopen("test.txt","r",stdin);
int N,K,i,j,k,temp;
scanf("%d%d",&N,&K);
getchar();
for(i=1;i<=N;i++){
c[i] = getchar()-'0';
}
for(i=1;i<=N;i++){
num[i][i] = c[i];
// printf("%d ",num[i][i]);
for(j=i+1;j<=N;j++){
num[i][j] = num[i][j-1]*10 + c[j];
// printf("%d ",num[i][j]);
}
// printf("\n");
}
for(i=1;i<=N;i++){
dp[i][0] = num[1][i];
}
for(i=2;i<=N;i++){
for(j=1;j<i && j<=K;j++){
for(k=j;k<i;k++){
if(dp[i][j] < (temp=dp[k][j-1]*num[k+1][i])){
dp[i][j] = temp;
}
}
}
}
printf("%d\n",dp[N][K]);
}