动态规划之最大K乘积

Posted 柳小茶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划之最大K乘积相关的知识,希望对你有一定的参考价值。

题目:

设I是一个n位十进制整数。如果将I分割为k段,则可得到k个整数。这k个整数的乘积称为I的一个k乘积。试设计一个算法,对于给定的I和k,求出I的最大k乘积。

测试样例:

输入 :

 2 1 (2是位数,1是分几段)
 15 (15是I)

输出:

15

 输入:

 5 2
12345

输出:

6170

 

最优子问题:

前k-1段的最优解*剩下的乘积 

#include<iostream>
using namespace std;
//分解成子问题是:前k-1段的最优解*剩下的乘积 最后能取得最优解
int cal(char num[],int i,int j){
    int v=0;
    while(j>=i){
        v=v*10+num[i]-'0';
        i++;
    }
    return v;
}
int main(){
    int n,k;
    cin>>n>>k;
    char num[n+1];
    int m[n+1][n+1];//m[i][j]就是求前i个数分成j段
    for(int i=1;i<=n;i++){
        cin>>num[i];
    }
    //数组打底
    m[1][1]=num[1]-'0';
    for(int i=2;i<=n;i++){//相当于把n位数 每次分成1段
        m[i][1]=m[i-1][1]*10+num[i]-'0';
    }
    //分成几段 -> 分段位置 -> 根据分段位置计算子问题(当前分段位置的上一个*剩下的数)
    for(int i=2;i<=k;i++){//表示分成几段
        int max=-1;
        for(int j=i;j<=n;j++){//从i开始因为 当i>j时 相当于把 3位数分成4段 没意义 所以j表示分段的j位数
            for(int d=1;d<=j-1;d++){//求解子问题 在j这几位数里面 遍历求分成i-1段和i段 不能超过j-1 
                int v=m[d][i-1]*cal(num,d+1,j);
                if(v>max)
                 max=v;
            }
            m[j][i]=max;
        }
    }
   cout<<m[n][k]<<endl;
}

 

 

 

 

 

 

 

 

 

以上是关于动态规划之最大K乘积的主要内容,如果未能解决你的问题,请参考以下文章

网易笔试题之合唱团---动态规划

ALGO-17 乘积最大(动态规划)

LeetCodeLeetCode之乘积最大子数组——枚举+动态规划+Kadane算法

剪绳子问题(动态规划,贪婪,递归)

动态规划_连续子数组的最大和

Codevs_1017_乘积最大_(划分型动态规划/记忆化搜索)