首页 > 学院 > 开发设计 > 正文

动态规划之大数乘积

2019-11-06 07:18:55
字体:
来源:转载
供稿:网友

题目要求

今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:

  设有一个长度为N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大。

  同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子:

  有一个数字串:312, 当N=3,K=1时会有以下两种分法:

  3*12=36   31*2=62

  这时,符合题目要求的结果是:31*2=62

  现在,请你帮助你的好朋友XZ设计一个程序,求得正确的答案。

输入格式

  程序的输入共有两行:   第一行共有2个自然数N,K(6≤N≤40,1≤K≤6)   第二行是一个长度为N的数字串。

输出格式

  输出所求得的最大乘积(一个自然数)。

  样例输入

  4 2   1231 样例输出 62


代码块

#include<stdlib.h>#include<stdio.h>#define MAXN 41#define MAXK 7int main(void){ int N, K; int i, j, k, m; int A[MAXN][MAXK]; int s[MAXN]; char num[MAXN]; int temp, max; PRintf("请输入数的个数,乘号的个数,以及具体的数:/n"); scanf("%d%d%s", &N, &K, num); for (i = 0; i < N; i++) { s[i + 1] = num[i]-'0'; } for (i = 1; i <= N; i++) { temp = 0; for (j = 1; j <= i; j++) { temp = temp * 10 + s[j];//可求得1个*时,个数分别为1,2,3,4的数的最大乘积 } //例如 1231; 1=0*10+1;12=1*10+2;123=(1*10+2)*10+3 A[i][0] = temp; // 1231=((1*10+2)*10+3)*10+1 } for (j = 1; j <= K; j++)//有几个乘号 { for (i = j + 1; i <= N; i++)//从第几位开始 1个*时最少从第1+1为开始计算 //2个*时 最少从2+1开始计算 { max = -999999; for (k = i; k > j; k--)//有几种选择 {//每一种选择的计算 temp = 0; //例如123 12*3=36 1*23=23 *后面的为第二部分 前面的为第一部分 for (m = k; m <= i; m++) { temp = temp * 10 + s[m];//这里计算第二部分 } temp = temp*A[k - 1][j - 1];//这里计算第一部分 max = max > temp ? max:temp; } A[i][j] = max;//i位数中有j个乘号的最大乘积 } } printf("%d", A[N][K]); system("pause"); return 0;}

测试结果

这里写图片描述


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表