题目:

【分析】
先通过若干个简单例子来观察规律,摸索思路。例如十进制整数 1234 划分为 3 段可有如下情形:
1 × 2 × 34 = 68
1 × 23 × 4 = 92
12 × 3 × 4 = 144(满足要求的解)
以计算正整数 1234 的最大 3 乘积为例,即 I = 1234,n = 4,k = 3(将 1234 分为 3 段)。由于计算乘积时要使用整数中的“一段”数字,则定义 w(s,t) 表示 I 中从第 s 位到第 t 位组成的数,如 w(2,3)=23;按照动态规划算法处理问题的步骤,定义 m(i,j) 表示整数 I 的前 i 位分成 j 段所得的“最大 j 乘积”,显然所求的问题即为计算 m(n,k)。
根据上述定义,显然有:
(1)当 i < j 时(这种情况下整数 I 的前 i 位无法分成 j 段),定义 m(i,j) = 0;
(2)当 j = 1 时(分为 1 段),有 m(i,j) = m(i,1) = w(1,i);
(3)当 j > 1且 j <= i 时,从 I 中的前 d 位数字(d 从 1 循环到i-1)可得到“最大 j-1 乘积(即 j-1 分段)”,然后乘以剩下的数字(组成 1 段,为 w(d+1,i),即从 d+1 位开始,到 I 的第 i 位),写成状态方程即为:

计算过程中会建立 2 个二维数组 W 和 M,前者是 n x n 阵,储存w(s,t) 的值(表示 I 中从第 s 位到第 t 位组成的数);后者是 n x k 阵,储存 m(i,j) 的值 。以计算正整数 1234 的最大 3 乘积为例,即 I = 1234,n = 4,k = 3,则有:

综上,可得m(i,j)的递推关系如下:

代码:
// 使用的库定义
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// ######################################################################## //
// //
// 下面是数据定义区 //
// //
// ######################################################################## //
#define STR_LEN 100
#define TRUE 1
#define FALSE 0
//////////////////////////////////////////////////////////////////////////////
// ######################################################################## //
// //
// 下面是各个子函数定义 //
// //
// ######################################################################## //
int CalcMaxKProduct( int n, int k, int **D, int **P ); //计算正整数的最大 k 乘积
void PrintProductMatrix( int n, int k, int **D, int **P );//显示计算数据
//////////////////////////////////////////////////////////////////////////////
// ######################################################################## //
// //
// 下面是各个子函数的实现 //
// //
// ######################################################################## //
// 使用动态规划法计算两个字符串之间的编辑距离 ...
//
// 测试数据如下 :
// ( 1 ) 1234 划分为 3 段 : 12 * 3 * 4 = 144
// ( 2 ) 自行设计 2 个测试用例
int CalcMaxKProduct( int n, int k, int **D, int **P )
{
int i, j, t, maxv, tk;
//当i<j无法进行分段
for(i = 1;i <= n;i++) //分成一段 j=1
{
P[i][1]= D[1][i];
}

3556

被折叠的 条评论
为什么被折叠?



