codeforces#308-E - Vanya and Brackets-枚举+表达式计算

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


你可能感兴趣的:(codeforces#308-E - Vanya and Brackets-枚举+表达式计算)