• 题解 P1018 【乘积最大】


    题目链接: P1018 乘积最大

    题面

    今年是国际数学联盟确定的“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设计一个程序,求得正确的答案。

    题意

    在一个长度为 N 的数字字符串中加上 K 个乘号,使所得表达式值最大。

    题解

    前言: 洛谷数据加强了,用(long long)只有60分,我不讲高精度乘法,只讲如何解这道题。

    1. 由题中"可将它分成K+1个部分"得出,这是区间划分类的题目。

    2. 要求找出区间最大值,因为乘号放在任何一个位置都不一定是等效的结果,有子结构。

    3. 要求最大值也就是间接性求最优子结构,子结构最优后的得出总体最优。符合无后效性。

    题面题意分析后可以得出这是一道区间划分DP题。

    1. 以加入的乘号数量作为划分阶段。

    2. (f[n][k]) 表示原数字前 n 位中加入 k 个乘号所得表达式的最大值。

    3. 预处理出 (a[i][j]) 表示原数字第 i 位到第 j 位组成的数字。

    4. (f[n][k] = max(f[i][k-1] * a[i+1][n],i∈[k,n)))

    代码(无高精度)

    #include<bits/stdc++.h>
    using namespace std;
    
    long long dp[45][45],num[45][45];
    bool tong[45][45];
    int n,k;
    char ch[45];
    
    inline void init()
    {
        cin >> n >> k;
        cin >> ch;
    
        for(int i = 0;i < n;i++)
        {
            for(int j = 0;j < n;j++)
            {
                if(i <= j)
                {
                    for(int k = i;k <= j;k++)
                    {
                        num[i][j]*=10;
                        num[i][j]+=ch[k]-'0';
                    }
                }
            }
        }
    }
    
    long long dfs(int n,int k)
    {
        if(k == 0) return num[0][n-1];
        if(tong[n-1][k-1]) return dp[n-1][k-1];
    
        for(int i = k;i < n;i++)
            dp[n-1][k-1] = max(dp[n-1][k-1],dfs(i,k-1)*num[i][n-1]);
    
        tong[n-1][k-1] = true;
    
        return dp[n-1][k-1];
    }
    
    int main(int argc, char const *argv[])
    {
        init();
        cout << dfs(n,k);
        getchar();getchar();getchar();
        return 0;
    }
    

    有不懂的可以加我qq:2832853025

  • 相关阅读:
    JavaScript replace() 方法
    vs2010注册码 激活方法
    Javascript 返回上一页
    错误:该行已经属于另一个表
    Oracle10g中如何分析响应时间
    Oracle Purge和drop的区别
    Oracle 的 Sql*Plus 常用命令介绍【转】
    如何实现oracle不同版本间数据的导入导出
    如何绑定变量使用
    Oracle PGA 介绍
  • 原文地址:https://www.cnblogs.com/Chicago/p/9920710.html
Copyright © 2020-2023  润新知