zoukankan      html  css  js  c++  java
  • 13- 整数划分插入乘号积最大(四)

    /*                                            整数划分(四)
    时间限制:1000 ms  |  内存限制:65535 KB
    难度:3

    描述

               暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近遇到了一个难题,让他百思不得其解,他非常郁闷。。亲爱的你能帮帮他吗?

              问题是我们经常见到的整数划分,给出两个整数 n , m ,要求在 n 中加入m - 1 个乘号,将n分成m段,求出这m段的最大乘积

    输入
        第一行是一个整数T,表示有T组测试数据
        接下来T行,每行有两个正整数 n,m ( 1<= n < 10^19, 0 < m <= n的位数);
    输出
        输出每组测试样例结果为一个整数占一行
    样例输入

        2
        111 2
        1111 2

    样例输出

        11
        121

    来源
        经典题目
    */
    //思路:区间dp,设dp[i][j] 表示在区间[0, i]之中,插入j个乘号可以得到的最大数
    //设a[i][j]为区间[i,j]所形成的数所以 dp[i][j] = max(dp[k][j-1] * a[k + 1][i])
     
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    ll dp[25][25];
    ll a[25][25];
    char b[25];

    ll fun(int i, int j){   //注意递归的条件
        if(dp[i][j] != 0)
            return dp[i][j];
        if(i < j)   //可以等于
            return 0;
        if(i == 0 || j == 0){
            return dp[i][j] = a[0][i];
        }
        for(int k = 0; k <= i - 1; k++){
            dp[i][j] = max(fun(k, j - 1)*a[k+1][i], dp[i][j]);
    //        cout << "k : " << k << " " << "i :" << i << " a: " << a[k+1][i] << " " << dp[i][j] << endl;
        }
        return dp[i][j];
    }

    int main(){
        int n;
        cin >> n;
        while(n--){
            memset(dp, 0, sizeof(dp));
            memset(b, 0, sizeof(b));
            memset(a, 0, sizeof(a));
            ll s = 0, m = 0;
    //        while(~scanf("%c", &b[s++]))
    //            ;    
            scanf("%s", b);    
            scanf("%lld", &m);
            s = strlen(b);
            if(m > s){
                cout << 0 << endl;
                continue;
            }
            for(int i = 0; i < s; i++){
                a[i][i] = b[i] - '0';
                for(int j = i + 1; j < s; j++){
                    a[i][j] = a[i][j - 1] * 10 + b[j] - '0';                
                }
            }
    //递归:
    //        printf("%lld ", fun(s - 1, m - 1));

    //递推:
            for(int i = 0; i < s; i++)
                dp[i][0] = a[0][i];
            for(int i = 1; i < s; i++){
                for(int j = 1; j <= m - 1; j++){
                    for(int k = 0; k < i; k++)
                        dp[i][j] = max(dp[i][j], dp[k][j - 1]*a[k+1][i]);                
                }
            }
            cout << dp[s-1][m-1] << endl;
    /*        
            for(int i = 0; i < s; i++){
                for(int j = 0; j < s; j++)
                    cout << a[i][j] << " ";
                cout << endl;        
            }
    */    
        }
        return 0;
    }

  • 相关阅读:
    将PHP文件生成静态文件源码
    Entity Framework Code First 学习日记(6)一对多关系
    Entity Framework Code First 学习日记(5)
    Entity Framework Code First 学习日记(3)
    Entity Framework Code First 学习日记(7)多对多关系
    Entity Framework Code First学习日记(2)
    Entity Framework Code First 学习日记(8)一对一关系
    Entity Framework Code First 学习日记(9)映射继承关系
    Entity Framework Code First 学习日记(10)兼容遗留数据库
    Entity Framework Code First 学习日记(4)
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/7429646.html
Copyright © 2011-2022 走看看