最大K乘积问题

来源:互联网 发布:中银淘宝校园卡未激活 编辑:程序博客网 时间:2024/05/08 01:51

问题描述:输入n和k,其中n为十进制数长度,k为分的段数,然后输入一个长度为n的十进制数,算出分成k段之后最大的乘积

例:输入1234

有以下结果 1x2x34=68,1x23x4=92,12x3x4=144,最大乘积为144

我们利用MaxI[n][k]表示长度为n的最大k乘积,用I(s,t)表示从s开始到t的十进制数,当我们的k=1时(即只分成一段)最大值就是本身即I(1,n);如果k>1,则我们的最大值就是前d的个数分成k-1的最大值乘以剩下的十进制数,即MaxI[n][k]=max{MaxI[d][k-1]*I(d+1,n)};

然后我们可以使用动态规划来解决问题

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<conio.h>#define MAXN 50#define MAXK 10//设置静态变量static int m[MAXN][MAXN];//m[i][j]表示前i个数的j乘积static int w[MAXN][MAXN];//w[i][j]表示从i到j的十进制数void MaxDp(int *a,int n,int k){int i,j,d;int max,temp;//初始化m数组for(i=1;i<=n;i++)m[i][1]=w[1][i];//动态规划求值/*  因为求的是m[n][k]的最大值  所以第一个for循环用来控制行数n*/   for(i=1;i<=n;i++){//第二个for循环用于控制列数k//由于第一列已经初始化,从j=2开始for(j=2;j<=k;j++){max=0;//第三个for循环用于动态规划,通过m[n][k]=m[d][k-1]+w[d+1][i]来求值for(d=1;d<i;d++){if((temp=m[d][j-1]*w[d+1][i])>max){max=temp;}m[i][j]=max;printf("\nm[%d][%d]*w[%d][%d]=%d\n",d,j-1,d+1,i,max);// printf("%d\t",m[i][j]);}}printf("\n");}  printf("\n\n\n");    for(i=1 ; i<= n; i++)    {                    for(j=1 ; j<= n; j++)            printf("%5d",m[i][j]);            printf("\n");    }//return max;}void main(){    int n,k,i,j;    int a[MAXN]={0},len=0;    char c ;printf("请输入长度和段数:");scanf("%d %d",&n,&k);fflush(stdin);printf("请输入长度为%d的十进制数:\n",n);//scanf("%s",a);while((c=getchar())!='\n'){       a[++len]=c-'0';//将字符转换成整形}    //初始化w二维数组for(i=1;i<=n;i++){w[i][i]=a[i];for(j=i+1;j<=n;j++){w[i][j]=w[i][j-1]*10+a[j];}}printf("w数组初始化后为:\n");for(i=1 ; i<= n; i++)    {            for(j=1 ; j<= n; j++)            printf("%5d",w[i][j]);            printf("\n");    }MaxDp(a,n,k);printf("最大%d乘积为:%d\n",k,m[n][k]);}

其中使用动态规划求解的核心代码为

 for(i=1;i<=n;i++){for(j=2;j<=k;j++){max=0;for(d=1;d<i;d++){if((temp=m[d][j-1]*w[d+1][i])>max){max=temp;}m[i][j]=max;printf("\nm[%d][%d]*w[%d][%d]=%d\n",d,j-1,d+1,i,max);// printf("%d\t",m[i][j]);}

最后得到的m[n][k]即为我们的最大k乘积的值

0 0
原创粉丝点击