区间DP 整数划分


状态方程就是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;
}


你可能感兴趣的:(dp,区间DP)