题目链接
https://www.luogu.org/problemnew/show/P1018
分析
这道题套路跟山区建小学差不多,可以先去看看那篇题解
$f[i][j]$表示枚举到第$i$位数,放了$j$个乘号的最大结果,同样的我们枚举区间断点看看新加入的乘号(也就是最后一个乘号)放在哪最大
没写高精打了表(捂脸)
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #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\n",f[n][k]); return 0; }
|