状态方程就是f[i][j]=Max(f[k][j-1]*a[k+1][i],f[i][j]);f[i][j]就是前i位分成j段的最大乘积,a[i][j]就是第i位到第j位的数字。附上CE代码(__int64修改为long long即可AC):
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<stdlib.h>
__int64 f[25][25],a[25][25];
__int64 ZH(__int64 n,int i,int j,int len)
{
int k;
char s[25]="";
__int64 x;
x=n;
for(k=len;k>=1;k--)
{
int d=x%10;
s[k]=d+'0';
x=x/10;
}
for(k=i;k<=j;k++)
x=x*10+s[k]-'0';
return x;
}
__int64 Max(__int64 x,__int64 y)
{
if(x<y)
return y;
return x;
}
int main()
{
int T,i,j,k;
scanf("%d",&T);
while(T--)
{
__int64 m,n;
scanf("%I64d %I64d",&n,&m);
memset(f,0,sizeof(f));
int len=log10(n)+1;
for(i=1;i<=len;i++)
{
for(j=i;j<=len;j++)
{
a[i][j]=ZH(n,i,j,len);
}
}
for(i=1;i<=len;i++)
f[i][1]=a[1][i];
for(i=2;i<=len;i++)
{
for(j=2;j<=m&&j<=i;j++)
{
for(k=1;k<i;k++)
{
f[i][j]=Max(f[k][j-1]*a[k+1][i],f[i][j]);
}
}
}
printf("%I64d\n",f[len][m]);
}
return 0;
}