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;
}