• 【dp】最大乘积


    题目描述】

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

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

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

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

    1)3*12=36

    2)31*2=62

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

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

    【输入】

    第一行共有2个自然数N,K(6≤N≤10,1≤K≤6)

    第二行是一个长度为N的数字串。

    【输出】

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

    【输入样例】

    4 2
    1231
    

    【输出样例】

    62

    【思路】:

    设f[i][k]表示在前i位数中插入K个乘号所得的最大值,a[j][i]表示从第j位到第i位所组成的自然数。用f[i][k]存储阶段K的每一个状态,

    f[i][k]=max{f[j][k-1]*a[j+1][i]}

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<stack>
    #include<vector>
    #include<map>
    #include<string>
    #include<cstring>
    using namespace std;
    const int maxn=999999999;
    const int minn=-999999999;
    inline int read() {
        char c = getchar();
        int x = 0, f = 1;
        while(c < '0' || c > '9') {
            if(c == '-') f = -1;
            c = getchar();
        }
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return x * f;
    }
    long long int n,k,a[1400][1400],f[1400][4100];
    int main() {
        cin>>n>>k;
        long long int t;
        cin>>t;
        for(int i=n; i>=1; --i) {
            a[i][i]=t%10;
            t/=10;
        }
        /* 拆分数*/
        for(int i=2; i<=n; ++i) {
            for(int j=i-1; j>=1; --j) {
                a[j][i]=a[j][i-1]*10+a[i][i];    
                //a[i][j]表示从i到j位的数 
            }
        }
        /*for(int i=1;i<=n;++i)
        {
            for(int j=1;j<=n;++j)
            {
                cout<<a[i][j]<<" ";
            }
            cout<<"
    ";
        }*/
        for(int i=1; i<=n; ++i) { //初始化成不带*的情况
            f[i][0]=a[1][i];
        }
        for(int t=1; t<=k; ++t) { //枚举乘号
            for(int i=t+1; i<=n; ++i) {
                for(int j=t; j<i; ++j) {
                    f[i][t]=max(f[i][t],f[j][t-1]*a[j+1][i]);
                    /*前i位中插入t个x号就是前j位插入t-1个x号在*后面的所有数*/
                }
            }
        }
        cout<<f[n][k];
        return 0;
    }
  • 相关阅读:
    bzoj1923 [Sdoi2010]外星千足虫(gauss)
    bzoj1013 [JSOI2008]球形空间产生器sphere(gauss)
    bzoj1013 [JSOI2008]球形空间产生器sphere(gauss)
    高斯消元(写(shui)题必备)
    随 (rand)(校内hu测10.6T1)(dp+矩阵+数论)
    随 (rand)(校内hu测10.6T1)(dp+矩阵+数论)
    题(problem)(详解10.5hu测T3:Catalan)
    题(problem)(详解10.5hu测T3:Catalan)
    高精度(模板)
    FJUT ACM 2144 并查集
  • 原文地址:https://www.cnblogs.com/pyyyyyy/p/10794400.html
Copyright © 2020-2023  润新知