码迷,mamicode.com
首页 > 其他好文 > 详细

jerry

时间:2019-11-13 16:23:00      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:alt   文件   def   void   --   existing   scanf   lib   和我   

jerry

题目描述

众所周知,Jerry 鼠是一只非常聪明的老鼠。

Jerry 聪明到它可以计算64 位有符号整形数字的加减法。

现在,Jerry 写下了一个只由非负整数和加减号组成的算式。它想给这个算式添加合法的括号,使得算式的结果最大。这里加减法的运算优先级相同,和我们在日常生活中接触到的一样,当没有括号时,先算左边的,再算右边的。

比如,算式 (1+2)+3-(4-5)+6(1+2)+3(45)+6 是合法的,但是 )1+2()1+2( 和 (-)1+2()1+2 以及 (1)+2(1)+2 都是不合法的。

输入格式

接下来,共有 TT 组数据,每组的格式如下:

第一行一个整数 nn,代表数字的个数。

接下来一行共 2n-12n1 个符号或非负整数,组成一个由空格隔开的算式。

输出格式

一行一个整数,代表添加括号后,算式最大的可能结果。

样例

样例输入1

1
3
5 - 1 - 3

样例输出1

7

样例1说明

5-(1-3) = 7

样例输入2

1
4
1 - 1 - 1 - 3

样例输出2

4

样例2说明

1- (1 - 1 - 3) = 4

样例3

下发了额外的一个大型样例文件。

数据范围与提示

测试点编号n的范围特殊性质
1 n \le 3n3
2,3 n \le 10n10 T \le 10T10
4,5 n \le 100n100 T \le 100T100
6,7 n \le 1000n1000 T \le 100T100
8,9,10 \sum {n} \le 2 \times 10^5n2×105

对于全部的数据, n \le 10^5 , \sum {n} \le 2 \times 10^5, 2 \le nn105,n2×105,2n,算式中出现的数字在 [0,10^9][0,109] 区间内。

来源

CSP-S 2019模拟 长沙一中2

 


Solution

 

令f[i][j]表示前i个数,前面有j个左括号的最大值。
在一个点可以加一个左括号,删一个左括号,或不改变。(删两个等价于不删,加两个...想啥呢)
那么就是n^2的了
题解告诉我只需要两层括号,于是就O(N)了
技术图片
#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 1000006
#define ll long long
#define inf 1e16
#define _(d) while(d(isdigit(ch=getchar())))
using namespace std;
int T,n;
ll f[maxn][3],a[maxn],g[maxn];
ll R(){
    int F=1,v;char ch;_(!)if(ch==-)F=0;v=(ch^48);
    _()v=(v<<1)+(v<<3)+(ch^48);return F?v:-v;
}
void work(){
    n=R();
    for(int i=1;i<=n;i++)a[i]=R();
    for(int i=0;i<=n;i++)
    for(int j=0;j<=2;j++)f[i][j]=-inf;
    g[0]=1;for(int i=1;i<=n;i++)g[i]=-g[i-1];
    f[0][0]=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<=2;j++){
            int v=g[j]*a[i];
            if(j>0&&a[i-1]<0)f[i][j]=max(f[i][j],f[i-1][j-1]+g[j]*a[i]);
            f[i][j]=max(f[i][j],f[i-1][j]+g[j]*a[i]);
            if(j<2)f[i][j]=max(f[i][j],f[i-1][j+1]+g[j]*a[i]);
        }
    }
    ll ans=-inf;
    for(int x=0;x<=2;x++)ans=max(ans,f[n][x]);
    printf("%lld\n",ans);
}
int main(){
    for(scanf("%d",&T);T--;work());
    return 0;
}
View Code

 

 
 

jerry

标签:alt   文件   def   void   --   existing   scanf   lib   和我   

原文地址:https://www.cnblogs.com/liankewei/p/11850039.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!