问题描述:设X是一个n位十进制整数,如果将X划分为K段,则可得到K个整数,这K个整数的乘积称为X的一个K乘积。请设计算法并编程实现,对于给定的X 和K,求出X的最大K乘积。
输入:X,K,n
输出:X的最大K乘积。
例如十进制整数 1234 划分为 3 段可有如下情形:
1 × 2 × 34 = 68
1 × 23 × 4 = 92
12 × 3 × 4 = 144
m[i][j] 表示: 从第i位到第j位所组成的十进制数
dp[i][j]表示前i位分成j段所得的最大乘积;i(1<=i<=n)的每轮循环,其中前N位数(1<=N<i)分成 j-1 段,乘后i-N位数字
#include<iostream>
#include <algorithm>
using namespace std;
int main()
{
int n, k, x;
cin >> x>>k>>n;
int dp[99][99] = { 0 };
int m[99][99];
int *a=new int[n];
int t1 = x;
int t2 = x;
for (int i = n; i >= 1; i--)
{
t2 = t1 % 10;
a[i] = t2;
t1 /= 10;
}
//m[i][j] 第i-j位组成的数
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];
}
}
//dp[i][j]前i位分成j段
//后n-i位最多分n-i段,则前i位最少分k-(n-i)段
for (int i = 1; i <= n; i++)//前i个数字
{
for (int j = 1; j <= i; j++)//分成j段
{
if (j > k)
break;
if (j < k - n + i)
continue;
if (j == 1) //分成1段则为自己
{
dp[i][j] = m[1][i];
continue;
}
for (int r = 1; r < i; r++) //前r位分成j-1段乘后i-r位的数字
{
dp[i][j] = max(dp[i][j], dp[r][j - 1] * m[r + 1][i]);
}
}
}
cout << dp[n][k] << endl;
return 0;
}