【题解】P1018 乘积最大

题面

题目传送门

前言

抛开高精度不谈,这题就是裸的区间 DP

正文

u1s1,很好想到记录 fi,j 表示枚举到第 i 个位置,用了 j 个乘号的最大值

简单转移一下即可!

最恶心的就是还得手搓高精度,需要维护两个操作

  • 乘法

  • 求较大值

P.S. 940 似乎超过 2128 力……所以 __int128 光速下班!

代码

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=45,maxk=8,maxl=1e6+10;
string s,f[maxn][maxk];
int a[maxl],b[maxl],c[maxl];
string work(int st,int ed){
    string res="";
    while(st<=ed){
        res+=s[st];
        st++;
    }
    return res;
}
inline string mul(string s1,string s2){
    int lena=s1.size(),lenb=s2.size(),x;
    for(int i=1;i<=lena;i++){
		a[i]=s1[lena-i]-'0';
	}
    for(int i=1;i<=lenb;i++){
		b[i]=s2[lenb-i]-'0';
	}
    for(int i=1;i<=lena+lenb;i++){
		c[i]=0;
	}
    for(int i=1;i<=lenb;i++){
        x=0;
        for(int j=1;j<=lena;j++){
            c[i+j-1]+=a[j]*b[i]+x;
            x=c[i+j-1]/10;
            c[i+j-1]%=10;
        }
        c[i+lena]=x;
    }
    string res;
    bool flag=0;
    for(int i=lena+lenb;i>0;i--){
		if(c[i]!=0){
		    for(int j=i;j>0;j--){
				res+=c[j]+'0';
			}
			flag=true;
			break;
		}
	}
    if(!flag){
		return "0";
	}
    return res;
}
inline string max(string s1,string s2){
    if(s1.size()!=s2.size()){
		return s1.size()>s2.size()?s1:s2;
	}
    return s1>s2?s1:s2;
}
int main(){
    int n,k;
    cin>>n>>k;
    char q;
    s.resize(1);
    for(int i=1;i<=n;i++){
    	cin>>q;
    	s+=q;
    }
    for(int i=1;i<=n;i++){
		f[i][0]=work(1,i);
	}
    for(int i=1;i<=n;i++){
		for(int j=1;j<=k;j++){
			for(int l=1;l<i;l++){
				f[i][j]=max(f[i][j],mul(f[l][j-1],work(l+1,i)));
			}
		}
	}
    cout<<f[n][k]<<endl;
    return 0;
} 

后记

惯将喜怒哀乐都融入粉墨……

完结撒花!

posted @   sunxuhetai  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示