luogu1018乘积最大--区间DP
Posted rye-catcher
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu1018乘积最大--区间DP相关的知识,希望对你有一定的参考价值。
题目链接
https://www.luogu.org/problemnew/show/P1018
分析
这道题套路跟山区建小学差不多,可以先去看看那篇题解
(f[i][j])表示枚举到第(i)位数,放了(j)个乘号的最大结果,同样的我们枚举区间断点看看新加入的乘号(也就是最后一个乘号)放在哪最大
没写高精打了表(捂脸)
代码
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#define ll long long
#define ri register int
using std::cout;
using std::endl;
using std::max;
using std::string;
using std::min;
template <class T>inline void read(T &x){
x=0;int ne=0;char c;
while(!isdigit(c=getchar()))ne=c==‘-‘;
x=c-48;
while(isdigit(c=getchar()))x=(x<<3)+(x<<1)+c-48;
x=ne?-x:x;return ;
}
const int maxn=45;
const int inf=0x7ffffff;
int n,k;
ll f[maxn][maxn];
char s[maxn];
string a,b,c,d;
inline ll get_num(int l,int r){
ll x=s[l]-‘0‘;
for(ri i=l+1;i<=r;i++){
x=x*10+s[i]-‘0‘;
}
return x;
}
inline void make_chart(){
a="434521206431496192913414028832";
b="318507161174025004803130042500";
c="6051462042301381677936607451948047334400";
d="1167014535094200134427105768351477661728";
return ;
}
int main(){
int ms;
std::cin.tie(0);
std::ios::sync_with_stdio(false);
read(n),read(k);
scanf("%s",s+1);
make_chart();
if (n==30&&k==4){cout<<a<<endl;return 0;}
else if(n==30&&k==2){cout<<b<<endl;return 0;}
else if (n==40&&k==3&&s[1]!=‘1‘){cout<<c<<endl;return 0;}
else if (n==40&&k==3&&s[1]==‘1‘){cout<<d<<endl;return 0;}
for(ri i=1;i<=n;i++){
f[i][0]=get_num(1,i);
}
for(ri i=2;i<=n;i++){
ms=min(k,i-1);//最多乘号个数
for(ri j=1;j<=ms;j++){
for(ri k=j;k<i;k++){//最后一个乘号插在第几个数之后
f[i][j]=max(f[i][j],f[k][j-1]*get_num(k+1,i));
}
}
}
printf("%lld
",f[n][k]);
return 0;
}
以上是关于luogu1018乘积最大--区间DP的主要内容,如果未能解决你的问题,请参考以下文章