最大k乘积问题
问题描述:设X是一个n位十进制整数,如果将X划分为K段,则可得到K个整数,这K个整数的乘积称为X的一个K乘积。请设计算法并编程实现,对于给定的X 和K,求出X的最大K乘积。
输入:
X,K,n
输出:
X的最大K乘积。
思路:
m(i,j)——表示第i位到第j位整数组成的(j-i+1)位整数;
dp(p,q)——表示前p位整数被划分为q段所得到的最大乘积;
[划分段数 > 整数位数,则结果为0]
初始子问题:(q=1时)
dp(p,1)=m(1,p)
无论多少位整数,被划分为一段,其最大k乘积均为其本身。
下一阶段子问题:(q>1且q<=p时)
dp(p,q)=max{dp(x,q-1)*m(x+1,p)}
(1<=x<=p-1)
p为整数分为q段,分别求出前x位这个数分为q-1段所得最大乘积与余下数段的乘积,选择合适的数据结构记录,然后进行比较,最大的结果即为dp(p,q)。
思路参考:
思路参考
#include<iostream>
using namespace std;
int x,k,n;
int a[44];
int dp[44][10];//前i个数中间有j个乘号
int m[44][44];
void init(){
for(int i=1;i<=n;i++)
m[i][i]=a[i];
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
m[i][j]=m[i][j-1]*10+m[j][j];
}
}
}
int main(){
cin>>x>>k>>n;
int xx=x;
for(int i=n;i>0;i--){
a[i]=xx%10;
xx=xx/10;
}
init();
for(int i=1;i<=n;i++)//枚举前i个数字
{
for(int j=0;j<i;j++)//枚举乘号个数
{
if(j==0)
{
dp[i][j]=m[1][i];
continue;
}
for(int k=1;k<i;k++)//枚举乘号位置
{
dp[i][j]=max(dp[i][j],dp[k][j-1]*m[k+1][i]);
}
}
}
cout<<dp[n][k-1]<<endl; //前n个数字分成n段,相当于前面添加n-1个乘号
return 0;
}