/*
                                                        最大k乘积问题        
题目内容:

设I是一个n位十进制整数.如果将I划分为k段,则可得到k个整数.这k个整数的乘积称为I的一个k乘积.试设计一个算法,对于给定的I和k ,求出I的最大k乘积.
Input
输入的第1行中有2个正整数n和k.正整数n是序列的长度;正整数k是分割的段数.接下来的一行中是一个n位十进制整数.(n<=10)
Output
输出计算结果,第1行中的数是计算出的最大k乘积.
n位十进制整数.(n<=10)

输入描述

输入的第1行中有2个正整数n和k.正整数n是序列的长度;正整数k是分割的段数.接下来的一行中是一个

输出描述

输出计算结果,第1行中的数是计算出的最大k乘积.

输入样例

2 1
15

输出样例

15
*/
//思路: 构造dp[i][k]表示从1到i位数分成k段的最大值,m[i][j]表示一个整数的第i位到j位构成的整数。
//递推关系: dp[i][k] = max(dp[i][k], dp[j][k - 1] * m[j+1][i],  1<=j<i; j表示分割的位置,枚举j,可以求得最大dp[i][k]

1.递归

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int dp[15][15];
int m[15][15];

int fun(int i, int k){   //递归求解,表示返回从1到i位数分成k份相乘的最大数
    if(k == 1)
        return dp[i][k] = m[1][i];
    if(dp[i][k] != 0)
        return dp[i][k];    
    for(int j = 1; j < i; j++){
        dp[i][k] = max(dp[i][k], fun(j, k - 1) * m[j + 1][i]);
    }
    return dp[i][k];
}

int main(){
    int n, k, s;
    while(~scanf("%d%d", &n, &k)){
        memset(m, 0, sizeof(m));
        memset(dp, 0, sizeof(dp));
        scanf("%d", &s);
        int S = 1;
        for(int i = 1; i <= n; i++)
            S *= 10;
        //初始话m数组,将s的i到j位数存在里面
        for(int i = 1; i <= n; i++){
            m[i][n] = s % S;
            S /= 10;
            for(int j = n - 1; j >= i; j--){
                m[i][j] = m[i][j + 1] / 10;
//                cout << m[i][j] << " ";
            }
//            cout << endl;
        }    
        cout << fun(n, k);
    }
    return 0;
}

2.递推:

#include <iostream>
using namespace std;
int dp[100][100];
int m[100][100];

int main(){
    int n, k, a;
    cin >> n >> k >> a;
    if(k == 1){
        cout << a;
        return 1;
    }
    int b = 1, q = 1;
    for(int i = n; i >= 1; i--){
        int p = 10;
        b = a / q;
        q *= 10;
//        cout << b << endl;
        for(int j = i; j >= 1; j--){
            m[j][i] = b % p;
            p *= 10;  
//            cout << m[j][i] << " ";
        }
    }
//    dp[1][1] = a;
    for(int i = 1; i <= n; i++){       //枚举前n个数字
        for(int j = 0; j <= i; j++){   //枚举乘号的个数
            if(j == 0){
                dp[i][j] = m[1][i];
                continue;    
            }
            for(int n = 1; n <= i; n++)//枚举乘号的位置
                dp[i][j] = max(dp[i][j], dp[n][j-1]*m[k+1][i]);
        }
    }
    cout << dp[n][k];
    return 0;
}

最新文章

  1. Golang汇编命令解读
  2. HTML5资料
  3. boost multi_index
  4. 存储过程中的when others then 和 raise
  5. JAVA并行框架:Fork/Join
  6. 405 Method Not Allowed
  7. PHP编写的图片验证码类文件分享方法
  8. 室内净化ThinkPHP复习
  9. ASP.NET基础笔记
  10. sqlalchemy 踩过的坑
  11. JavaScript DOM详解
  12. SpringMVC概述
  13. 启动sql2012时出现Cannot find one or more components.Please reinstall the application
  14. 利用twilio进行手机短信验证
  15. Linux系统(centos)同步时间方式
  16. Centos7下搭建LAMP环境,安装wordpress(不会生产博客,只是一名博客搬运工)(菜鸟)
  17. 项目启动一直死循环 DruidDataSource.init 方法
  18. hdu 6185 递推+【矩阵快速幂】
  19. 什么是spu和sku
  20. Swift - 用UIScrollView实现视差动画效果

热门文章

  1. UMG设置组件自适应居中或靠边
  2. javascript继承之组合继承(三)
  3. 6.27-JSTL、标签、分页
  4. PHP的mysqli_query参数MYSQLI_STORE_RESULT和MYSQLI_USE_RESULT的区别
  5. 关于Node和Deno
  6. 解决QT出现XXXX.dll不能加载问题
  7. ASCII和万国码
  8. linux更新系统
  9. eval是只读数据,bind是可更新的.
  10. PHP依赖注入(DI)和控制反转(IoC)详解