2019蓝桥杯初赛 后缀表达式

http://oj.ecustacm.cn/problem.php?id=1467

 

蓝桥赛前练练手~~

 

后缀表达式可以模拟任意加括号的结果

所以相当于给出n个加号,m个减号,n+m+1个数,用这些任意组成一个式子,使结果最大

用大写字母表示正数,小写字母表示负数

最优的情况是n+m+1个数中,有n+1个正数,有m个非正数

即构成A+B+C+D-a-b-c形式

结果就是绝对值之和

 

在此基础上

如果减号多了,说明需要给正数前分配减号

1、如果有非正数,那么可以构成A-(a-B)=A-a+B,依然是绝对值之和

2、如果全是正数,那么可以构成A-(B-C)=A-B+C,显然需要B最小,结果就是绝对值之和-2*最小正数

如果加号多了,说明需要给负数前分配加号

1、如果没有减号,那么只能是A+a+b,结果就是所有数的和

2、如果有减号而且有正数,那么可以构成A-(a+b)=A-a-b,结果是绝对值之和

    如果有减号而且没有正数,a-(b+c)=a-b-c,需要a最大,结果就是绝对值之和+2*最大非正数

 

#include<cstdio>
#include<algorithm>

using namespace std;

#define N 100001 

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int tot=n+m+1,x,s1=0,s2=0;
    long long sa=0,sb=0;
    int mi=1e9;
    for(int i=1;i<=tot;++i) 
    {
        scanf("%d",&x);
        if(x>0) s1++,sa+=x;
        else s2++,sb-=x;
        mi=min(mi,abs(x));
    }
    if(m==s2) printf("%lld",sa+sb);
    else if(m>s2)
    {
        if(s2) printf("%lld",sa+sb);
        else printf("%lld",sa+sb-2*mi);
    }
    else
    {
        if(m) 
        {
            if(s1) printf("%lld",sa+sb);
            else printf("%lld",sb-2*mi);
        }
        else printf("%lld",sa-sb);
    }
}

 

posted @ 2020-10-05 20:08  TRTTG  阅读(818)  评论(0编辑  收藏  举报