【GMOJ6804】模拟jerry

题目

题目链接:https://gmoj.net/senior/#main/show/6804
众所周知,Jerry 鼠是一只非常聪明的老鼠。Jerry 聪明到它可以计算 64 位有符号整形数字的加减法。现在,Jerry 写下了一个只由非负整数和加减号组成的算式。它想给这个算式添加合法的括号,使得算式的结果最大。这里加减法的运算优先级相同,和我们在日常生活中接触到的一样,当没有括号时,先算左边的,再算右边的。比如,算式 (1+2)+3−(4−5)+6 是合法的,但是 )1+2( 和 (−)1+2 以及 −(1)+2 都是不合法的。

思路

括号嵌套括号最多只会嵌套两层,因为嵌套三层之后等价于没有套。
发现只有在 - 后面加括号才会改变答案,所以我们固定在 + 后边一定不能加括号,设 \(f[i][j]\) 表示处理到第 \(i\) 个数字,在第 \(j\) 层括号的最大和。如果 \(j=1\) 需要变号。
分类当前符号简单转移即可。时间复杂度 \(O(n)\)

思路

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=200010;
int Q,n,x;
ll f[N][3];
char ch[3];

int main()
{
	freopen("jerry.in","r",stdin);
	freopen("jerry.out","w",stdout);
	scanf("%d",&Q);
	while (Q--)
	{
		f[1][1]=f[1][2]=-1000000000000000000LL;
		scanf("%d%lld",&n,&f[1][0]);
		for (int i=1;i<n;i++)
		{
			scanf("%s%d",ch,&x);
			if (ch[0]=='+')
			{
				f[i+1][0]=max(f[i][0]+x,f[i][1]-x);
				f[i+1][1]=max(f[i][1]-x,f[i][2]+x);
				f[i+1][2]=f[i][2]+x;
			}
			else
			{
				f[i+1][0]=max(f[i][0]-x,f[i][1]+x);
				f[i+1][1]=max(f[i][0]-x,max(f[i][1]+x,f[i][2]-x));
				f[i+1][2]=max(f[i][1]+x,f[i][2]-x);
			}
		}
		printf("%lld\n",max(f[n][0],max(f[n][1],f[n][2])));
	}
	return 0;
}
posted @ 2020-10-14 19:44  stoorz  阅读(148)  评论(0编辑  收藏  举报