题解:2018级算法第四次上机 C4-最小乘法

Posted doulikewyx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解:2018级算法第四次上机 C4-最小乘法相关的知识,希望对你有一定的参考价值。

题目描述:

 技术图片

 

 

 

样例:

 技术图片

 

 

 

实现解释:

和字符串处理结合的动态规划,个人认为比较难分析出状态转移方程,虽然懂了之后挺好理解的

知识点:

动态规划,字符串转数字

 

题目分析:

首先按照最基础:依据题意设计原始dp数组,这里根据描可知有三个数需要考虑:数字串开始,数字串结尾和之间插入的乘号数量,因此基础dp[i][j][k],分别为开始,结束脚标和乘号数。

然后推导:考虑到添加乘号,为了使状态转移方程简单,最后固定位置,因此可以考虑每次都在最后插入乘号,插入乘号的位置便可倒序确定。此时数字串的开始位置便可固定为0(因为添加乘号都在最后添加,因此可以不必考虑开始),则有dp[i][j],分别为结束脚标和乘号数量。

得出状态转移方程:乘号在最后插入,插入之间有j-1个乘号,前面有i+1个数字,因此插入乘号的位置可从j+1一直到i-1脚标的数字后(保证能放下j个乘号),则需要比较的就是dp[i][j]和dp[i-k][j-1]*getNum(i-k+1,i);k为插入乘号后最后一个数字的位数(根据脚标范围而定),前者即插入乘号前面的最大值,后者即乘号后面的值,循环找最大既是dp[i][j]的最大值。

 

注:初始化需要对插入0个乘号时dp[i][0]进行特殊处理,其他均为0

 

难点:

状态转移方程的实现,状态转移时数字字符串脚标的确定

 

完整代码:

技术图片
#include<iostream>
#include<cstring>
#include<sstream>
using namespace std;
long long dp[20][15];
string num;
long long getNum(int i,int j)
{
    string temp = num.substr(i,j-i+1);
    //基于开始脚标和长度截取字符串 
    stringstream ss;
    long long strnum;//由于最大18位,因此可以直接转化 
    ss << temp;//传入流 
    ss >> strnum;//流导出自动转化数字 
    return strnum;
}
int main()
{
    ios::sync_with_stdio(false); 
    int n,length,minc,maxl;
    long long now;
    while(cin >> n)
    {
        cin >> num;
        length = num.length();
        memset(dp,0,sizeof(dp));
        //0个乘号时赋初值,这里用dp[i-1][0]*10+num[i]-‘0‘的方法更快些 
        for(int i = 0;i<length;i++) dp[i][0] = getNum(0,i);
        //0的已经处理,从1开始 
        for(int i = 1;i<length;i++)//当前到达的字符串脚标为i 
        {
            minc = min(n,i);//最多可放的乘号数 
            for(int j = 1;j<=minc;j++)//0~i中插入j个乘号
            {
                maxl = i-j+1;//插入的极限位置界定,依据i>=k+j-1得出 
                for(int k = 1;k<=maxl;k++)//k为插入称号后最后一个数字的位数
                {
                    //乘号的插入位置为即i-k脚标的数字后 
                    //因此获取数字时i-k+1即最后数字的开始脚标 
                    now = dp[i-k][j-1]*getNum(i-k+1,i);//加快计算 
                    if(now > dp[i][j])
                    {
                        dp[i][j] = now;
                    }
                }
            }
        }
        cout << dp[num.length()-1][n] << 
;
    }
    return 0;
}
View Code

 

以上是关于题解:2018级算法第四次上机 C4-最小乘法的主要内容,如果未能解决你的问题,请参考以下文章

2016级算法第四次上机-D.AlvinZH的1021实验plus

2016级算法第四次上机-F.AlvinZH的最“长”公共子序列

2016级算法第四次上机-B ModricWang的序列问题

2016级算法第四次上机-G.ModricWang的序列问题 II

2016级算法第四次上机-E.Bamboo and the Ancient Spell

2016级算法第四次上机-A.Bamboo 和人工zz