Luogu-P1018 乘积最大

Posted seanocean

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu-P1018 乘积最大相关的知识,希望对你有一定的参考价值。

题目

题目链接

技术图片

技术图片

 

测试得分:  60

 

 

主要算法 :  动态规划,高精动规,区间动规

 

 

 

题干:

    区间动规板子

 

 

应试策略:

  将所有的字符转化为数字形式存储在a[i][j]中,a[i][j]表示的是从i到j的数字形式,f[i][j]表达的是在前j个数中,划分为i+1部分的乘积,先将f[0][i]初始状态划分a[1][i]

  先枚举划分的部分,再进行判断区间的末端,进而再确定划分的位置,进行状态方程转移f[i][j]=max(f[i][j],f[i-1][l]*a[l+1][j]);

  

   代码

 

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#define LL long long 
#define FORa(i,s,e) for(int i=s;i<=e;i++)
#define FORs(i,s,e) for(int i=s;i>=e;i--)
#define gc pa==pb&&(pb=(pa=buf)+fread(buf,1,100000,stdin),pa==pb)?EOF:*pa++
#define File(name) freopen(name".in","r",stdin);freopen(name".out","w",stdout);

using namespace std;
static char buf[100000],*pa=buf,*pb=buf;
inline int read();

const int K=6,N=40;
string s;
LL k,n,f[K+1][N+1],a[N+1][N+1];//a[i][j]将i-j字符转换为数字形式,f[i][j]代表在前j个数中划分i+1部分的最大乘积 
int main()

    scanf("%d%d",&n,&k);
    cin>>s;
    FORa(i,1,n) FORa(j,i,n) a[i][j]=a[i][j-1]*10+s[j-1]-0;//处理成数字形式 
    FORa(i,1,n) f[0][i]=a[1][i];
    FORa(i,1,k)
        FORa(j,1,n)
            FORa(l,i-1,j-1)//注意最小值为k-1,而不是i,自己思考一下为什么这样 
                f[i][j]=max(f[i][j],f[i-1][l]*a[l+1][j]);
    printf("%lld",f[k][n]);
    return 0;

inline int read()

    register int x(0);register int f(1);register c(gc);
    while(c<0||c>9) f=c==-?-1:1,c=gc;
    while(c>=0&&c<=9) x=(x<<1)+(x<<3)+(c^48),c=gc;
    return  x*f;

 

 

 

总结:

  注意边界,判断数据的大小(此处需打高精)

 

 

 

 

 

 

 

技术图片

以上是关于Luogu-P1018 乘积最大的主要内容,如果未能解决你的问题,请参考以下文章

Luogu - P1018 乘积最大 - 题解

P1018 乘积最大

洛谷 P1018 乘积最大

luogu1018乘积最大--区间DP

洛谷P1018乘积最大——区间DP

[洛谷] P1018 乘积最大