1 solutions

  • 0
    @ 2023-11-28 22:08:05

    首先注意到,把括号加在乘号之间和加在加号之间都是没有用处的。

    例如,a+b+c+d=a+(b+c)+d , 而加在乘号和加号之间一定又是不劣的。 先考虑一个乘号的情形,显然 (a+b)*c 一定大于等于 a+b*c 。 如果有一连串的乘号呢?可以发现 (a+b*c*d)*e 一定劣于 (a+b)*c*d*e ,证明只需拆开括号即可。 所以,最后答案的括号添加一定是这种形式: a*b*......*(c+[乘积式或常数项]+......+[乘积式或常数项]+f)*......*g*h*i 两端的乘积串被最大限度地拆开了。

    于是这个题就完成了,我们枚举起始的乘积式,再枚举末尾的乘积式,并预处理乘积式与常数项的前缀和进行计算,复杂度 O(n2)O(n^2) ,注意在两段均为乘积式的情况下枚举分界点靠左侧还是右侧即可。 stdstd 对字符串的处理方法是以每个加号为分界,把式子处理成 [乘积式或常数项]+[乘积式或常数项]...... 的形式,具体如何进行的详见 stdstdprepre 函数。

    #include <bits/stdc++.h>
    #define INF 0x7fffffff
    #define MAXN 5005
    #define eps 1e-9
    #define foru(a,b,c)	for(int a=b;a<=c;a++)
    #define RT return 0;
    #define LL long long
    #define int LL
    #define LXF int
    #define RIN rin()
    #define HH printf("\n")
    #define fi first
    #define se second
    using namespace std;
    inline LXF rin(){
    	LXF x=0,w=1;
    	char ch=0;
    	while(ch<'0'||ch>'9'){ 
    	if(ch=='-') w=-1;
    	ch=getchar();
    	}
    	while(ch>='0'&&ch<='9'){
    	x=x*10+(ch-'0');
    	ch=getchar();
    	}
    	return x*w;
    }
    string s;
    class Obj{
    	public:
    		int ty,a,b,c;
    }ls[MAXN];
    int cnt=0;
    vector<int> opt;
    vector<Obj> res;
    void pre(){
    	//work to format as vector[a opt b opt c]
    	int v=0;
    	for(auto c:s){
    		if(c=='+'){
    			opt.push_back(v);
    			opt.push_back(1);
    			v=0;
    		}else if(c=='*'){
    			opt.push_back(v);
    			opt.push_back(2);
    			v=0;
    		}else{
    			v=v*10+(c-'0');
    		}
    	}
    	opt.push_back(v);
    	
    	//work to format as array[Obj + Obj + Obj] unc
    	for(int l=-1,r;l<(int)opt.size();l=r){
    		r=l+2;
    		while(r<opt.size() && opt[r]!=1)	r+=2;
    		if(r==l+2){
    			ls[++cnt]={0,opt[l+1],1,1};
    		}else{
    			ls[++cnt]={1,opt[l+1],1,opt[r-1]};
    			for(int i=l+3;i<=r-3;i+=2){
    				ls[cnt].b*=opt[i];
    			}
    		}
    	}
    	
    	//work to format as vector[Obj + Obj + Obj] unique
    	for(int i=1;i<=cnt;i++){
    		if(res.empty() || res[res.size()-1].ty!=0 || ls[i].ty!=0){
    			res.push_back(ls[i]);
    		}else{
    			res[res.size()-1].a+=ls[i].a;
    		}
    	}
    }
    int ans=0,sum[MAXN];
    signed main(){
    	cin>>s;
    	pre();
    	for(int i=0;i<res.size();i++){
    		sum[i+1]=sum[i]+res[i].a*res[i].b*res[i].c;
    	}
    	ans=sum[res.size()];
    	for(int l=0;l<res.size();l++){
    		for(int r=l+1;r<res.size();r++){
    			if(res[l].ty!=1 || res[r].ty!=1)	continue;
    			ans=max(ans,sum[l]+(sum[res.size()]-sum[r+1])+res[l].a*res[r].c*(res[l].b*res[l].c+res[r].a*res[r].b+sum[r]-sum[l+1]));
    			ans=max(ans,sum[l]+(sum[res.size()]-sum[r+1])+res[l].a*res[l].b*res[r].c*(res[l].c+res[r].a*res[r].b+sum[r]-sum[l+1]));
    			ans=max(ans,sum[l]+(sum[res.size()]-sum[r+1])+res[l].a*res[r].b*res[r].c*(res[l].b*res[l].c+res[r].a+sum[r]-sum[l+1]));
    			ans=max(ans,sum[l]+(sum[res.size()]-sum[r+1])+res[l].a*res[l].b*res[r].b*res[r].c*(res[l].c+res[r].a+sum[r]-sum[l+1]));
    		}
    		if(res[l].ty==1){
    			// cout<<l<<endl;
    			ans=max(ans,(sum[l]+res[l].a*res[l].b)*res[l].c+sum[res.size()]-sum[l+1]);
    			ans=max(ans,(sum[l]+res[l].a)*res[l].b*res[l].c+sum[res.size()]-sum[l+1]);
    			
    			ans=max(ans,(sum[res.size()]-sum[l+1]+res[l].b*res[l].c)*res[l].a+sum[l]);
    			ans=max(ans,(sum[res.size()]-sum[l+1]+res[l].c)*res[l].a*res[l].b+sum[l]);
    		}
    	}
    	cout<<ans;
    	return 0;
    }
    
    • 1

    Information

    ID
    271
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    7
    Tags
    (None)
    # Submissions
    20
    Accepted
    9
    Uploaded By