zoukankan      html  css  js  c++  java
  • jerry

    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 imes 10^5n2×105

    对于全部的数据, n le 10^5 , sum {n} le 2 imes 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
    ",ans);
    }
    int main(){
        for(scanf("%d",&T);T--;work());
        return 0;
    }
    View Code
     
     
  • 相关阅读:
    2017-2018-2 20155206 《网络对抗技术》 实验六:信息搜集与漏洞扫描
    20155206 Exp5 MSF基础应用
    20155206 实验4 恶意代码分析
    20155206《网络攻防》第三次实验_免杀及其原理
    20155206 Exp2 后门原理与实践
    20155206赵飞 Exp1PC平台逆向破解及Bof基础实践
    J-19 集合对象
    J-18 集合对象
    J-17 集合对象
    J-16 集合对象
  • 原文地址:https://www.cnblogs.com/liankewei/p/11850039.html
Copyright © 2011-2022 走看看