Codeforces 552E - Vanya and Brackets【表达式求值】
给一个只有加号和乘号的表达式,要求添加一对括号使得最后结果最大。表达式长度5000,乘号最多12个,表达式中数字只有1位。
左括号一定在乘号右边,右括号一定在乘号左边,因为如果不是这样的话,一定可以调整括号的位置使表达式的值增大。
于是只要枚举括号的位置然后计算表达式即可。【以上来源,懒得自己写了】
做到这道题的时候突然发现自己忘记表达式求值怎么求了
这个表达式只有括号,加号和乘号
大概用到了后缀表达式的思想,但不会去真正化成后缀表达式
建两个栈,一个char类型,一个int类型
从左到右扫描,
如果是数,则直接压入int栈中
如果是'*'或者'(',则将其加入char栈中
如果是是')',则不断地将符号从char栈中取出来,直到遇到'(',最后在把'('弹出
每从char中取出一个元素,
从int栈中取出两个元素,进行相应的操作,然后重新放回int栈中。
当扫描完整个表达式后,如果char栈中还有符号,
不断地弹出弹出,操作同上。。
就这样:)
#include<bits/stdc++.h> #define eps 1e-9 #define FOR(i,j,k) for(int i=j;i<=k;i++) #define MAXN 1005 #define MAXM 40005 #define INF 0x3fffffff #define PB push_back #define MP make_pair #define X first #define Y second #define lc (k<<1) #define rc ((k<<1)1) using namespace std; typedef long long LL; LL i,j,k,n,m,x,y,T,ans,big,cas,num,len; bool flag; stack<char> tt; stack<LL> an; char ss[5005]; char s[5005]; LL calc(LL l,LL r) { LL i,j; while (!tt.empty()) tt.pop(); LL nn=0; while (!an.empty()) an.pop(); for (i=0;i<len;i++) { if (i==r) { char c=tt.top(); while (c!='(') { LL u=an.top();an.pop(); LL v=an.top();an.pop(); if(c=='+') an.push(u+v); else if (c=='*') an.push(u*v); tt.pop(); c=tt.top(); } tt.pop(); } if (s[i]=='*') tt.push(s[i]);else if (s[i]=='+') { while (!tt.empty() && tt.top()=='*') { LL u=an.top();an.pop(); LL v=an.top();an.pop(); an.push(u*v); tt.pop(); } tt.push(s[i]); }else if (s[i]>='0' && s[i]<='9') { an.push(s[i]-'0'); } if (i==l) { tt.push('('); } } while (!tt.empty()) { char c=tt.top(); LL u=an.top();an.pop(); LL v=an.top();an.pop(); if(c=='+') an.push(u+v); else if (c=='*') an.push(u*v); tt.pop(); } return an.top(); } vector<LL> mul; int main() { scanf("%s",s+2); s[0]='1'; s[1]='*'; len=strlen(s); s[len]='*'; s[len+1]='1'; s[len+2]=0; len=strlen(s); //printf("%s\n",s); mul.clear(); for (i=0;i<len;i++) { if (s[i]=='*') mul.PB(i); } ans=0; for (i=0;i<mul.size();i++) { for (j=i+1;j<mul.size();j++) { LL tmp=calc(mul[i],mul[j]); ans=max(ans,tmp); } } printf("%I64d\n",ans); return 0; }