首页 > 其他 > 详细

洛谷 1816 乘积最大

时间:2019-10-22 21:51:17      阅读:95      评论:0      收藏:0      [点我收藏+]

这题的考点涉及了高精度(乘法)模拟和动态规划。

状态设计:dp[i][j]这个结构体表示在i个数中间放j个乘号的最大结果。

转移方程:我们需要枚举最后一个乘号是在哪里放的,直接计算一下最后一个乘号之前的数字加入k-1个乘号时的最大值,再乘以最后一个乘号之后的数字。

高精在这题有这几个应用:

1.取数 将没有乘号分隔的连续的数字变成一个数,进行运算

2.比较 没有比较哪来的最大值

3.乘法 将乘号两边取到的数乘起来

 

#include<bits/stdc++.h>
using namespace std;
const int N=100;
int n,K,a[N];
string s;
struct node
{
    int len,ans[N];
}dp[N/10][N];
node cal(node x,int l,int r)
{
    node answ,y;
    memset(answ.ans,0,sizeof(answ.ans));
    memset(y.ans,0,sizeof(y.ans));
    y.len=r-l+1;
    for(int i=r;i>=l;i--)    y.ans[r-i+1]=a[i];
    int len1=x.len,len2=y.len,len;
    for(int i=1;i<=len1;i++)
        for(int j=1;j<=len2;j++)
            answ.ans[i+j-1]+=x.ans[i]*y.ans[j];
    len=len1+len2-1;
    for(int i=1;i<=len;i++)
    {
        answ.ans[i+1]+=answ.ans[i]/10;
        answ.ans[i]%=10;    
    } 
    if(answ.ans[len+1])    len++;
    answ.len=len;
    return answ;
}
node cmp(node x,node y)
{
    int lenx=x.len,leny=y.len;
    if(lenx<leny)    return y;
    if(lenx>leny)    return x;
    for(int i=lenx;i>=1;i--)
    {
        if(x.ans[i]>y.ans[i])    return x;
        if(x.ans[i]<y.ans[i])    return y;
    }
    return x;
}
int main()
{
    scanf("%d%d",&n,&K);
    cin>>s;
    for(int i=1;i<=n;i++)    a[i]=s[i-1]-0;
    for(int i=1;i<=n;i++)
        for(int j=i;j>=0;j--)
            dp[0][i].ans[++dp[0][i].len]=a[j];
    for(int i=2;i<=n;i++)
        for(int k=1;k<=min(K,i-1);k++)
            for(int j=k;j<i;j++)
                dp[k][i]=cmp(dp[k][i],cal(dp[k-1][j],j+1,i));
    for(int i=dp[K][n].len;i>=1;i--)
        printf("%d",dp[K][n].ans[i]);
    return 0;
}

 

洛谷 1816 乘积最大

原文:https://www.cnblogs.com/Siv0106/p/11722293.html

(1)
(1)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!