最大k乘积问题
设I是一个n位十进制整数。如果将I分割为k段,则可得到k个整数。这k个整数的乘积称为I的一个k乘积。试设计一个算法,对于给定的I和k,求出I的最大k乘积。
样例输入
54321 5
样例输出
6420
解:
最大k乘积问题:
首先将给给定的数字I分割放到数组a[i]中
定义数组w[i][j]存放i到j所代表的整数,在init中(第一位下标从1开始)进行赋值
定义dp[i][j] 前i个数分成j段的最大乘积所以dp[i][1]=w[1][1]
在动态规划过程中 将要将前i个数字分割成j段,则将前d个数字分成j-1段,将最后i-d个数字作为一段
两段的乘积作为前i个数字分割成j段的乘积,从中选取最大值作为dp[i][j]的值
此时 d个数字分成j-1段为:dp[d][j-1], 将最后i-d个数字作为一段为:w[d+1][i](即从d+1到i所代表的数)
即: dp[i][j]=max{dp[d][j-1]*w[d+1][i]}
#include <stdio.h>
#include <math.h>
#define MAX(a,b) a>b?a:b
int w[100][100]; //存放i到j代表的整数
int dp[100][100]; //前i个数分成j段的最大乘积
void init(int I,int len)
{
int a[100]={0};
int index=len;
while(I){
a[index--]=I%10;
I/=10;
}
for(int i=1;i<=len;i++)
{
for(int j=i;j<=len;j++)
{
int temp=0;
for(int k=i;k<=j;k++)
{
temp=temp*10+a[k];
}
w[i][j]=temp;
}
}
for(int i=1;i<=len;i++)
{
dp[i][1]=w[1][i];
}
}
//dp[i][1]=w[1][i]
//dp[i][j]=max{dp[d][j-1]*w[d+1][i]}
int main()
{
int I,k;
scanf("%d %d",&I,&k);
int len=log10(I)+1;
init(I,len);
for(int i=1;i<=len;i++)
{
for(int j=2;j<=k;j++)
{
int maxvalue=0;
for(int d=1;d<i;d++)
{
int temp=dp[d][j-1]*w[d+1][i];
maxvalue=MAX(maxvalue,temp);
}
dp[i][j]=maxvalue;
}
}
printf("%d\n",dp[len][k]);
return 0;
}