http://codeforces.com/contest/552/problem/E
题意:
给一个不带括号的 只有加法和乘法的 表达式
让你给它加一对括号,使得值最大
乘法操作不超过15个。 表达式长度不超过5001
思路:
由于只有称乘号和加号,可以猜测括号的位置,
最优的方法应该是,左括号在乘法右边,右括号在乘法左边
因为如果不是这样的话,可以调整使得结果更大。
因此只需要枚举所有乘号的位置,注意可能第一个位置就被左括号括起来,所以可以假设第一个位置前面也有一个乘号,同理,最后一个位置也可以插一个乘号。
每次枚举两个乘号,然后计算该值即可,表达式计算用栈模拟即可咯。
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <algorithm> #include <stack> #include <map> #include <set> #include <vector> #include <iostream> using namespace std; const double pi=acos(-1.0); double eps=0.000001; __int64 min(__int64 a,__int64 b) {return a<b?a:b;} __int64 max(__int64 a,__int64 b) {return a>b?a:b;} char s[5005]; vector<__int64> pos; stack<__int64> num; stack<char> op; inline __int64 result (__int64 a,__int64 b,char c) { return (c=='*')?(a*b):(a+b); } void cal() { char type=op.top(); op.pop(); __int64 a=num.top(); num.pop(); __int64 b=num.top(); num.pop(); num.push(result(a,b,type)); } __int64 expression(string s) { __int64 i; for (i=0;i<s.length();i++) { char cc=s[i]; if (cc>='0'&&cc<='9') num.push(cc-'0'); else if (cc=='(') op.push(cc); else if (cc==')') { while(op.top()!='(') cal(); op.pop(); } else if (cc=='+') { while(!op.empty()&&op.top()=='*') cal(); op.push('+'); } else op.push('*'); } while(!op.empty()) cal(); return num.top(); } int main() { __int64 i,j; scanf("%s",s+1); __int64 len=strlen(s+1); __int64 ok=0; pos.push_back(1); for (i=1;i<=len;i++) { if (s[i]=='*') pos.push_back(i); } pos.push_back(len+1); __int64 n=pos.size(); __int64 ans=expression(s+1); for (i=0;i<n;i++) { for(j=i+1;j<n;j++) { string str=s+1; //pr__int64f("%I64d-%I64d\n",pos[i],pos[j]); str.insert(pos[i],"("); str.insert(pos[j],")"); ans=max(ans,expression(str)); } } printf("%I64d\n",ans); return 0; }