后缀表达式(贪心)————第十届蓝桥杯省赛C++B组

后缀表达式

给定 N 个加号、M 个减号以及 N+M+1 个整数 A1,A2,⋅⋅⋅,AN+M+1,小明想知道在所有由这 N 个加号、M 个减号以及 N+M+1 个整数凑出的合法的后缀表达式中,结果最大的是哪一个?

请你输出这个最大的结果。

例如使用 123+−,则 “23+1−” 这个后缀表达式结果是 4,是最大的。

输入格式
第一行包含两个整数 N 和 M。

第二行包含 N+M+1 个整数 A1,A2,⋅⋅⋅,AN+M+1。

输出格式
输出一个整数,代表答案。

数据范围
0≤N,M≤105,
−109≤Ai≤109
输入样例:
1 1
1 2 3
输出样例:
4

题解分析

设a1,a2,…an为题目中输入的数组,数可正可负,题目给定负号和正号的数量,求表达式最大值

如果至少有一个负号,那么我们可以用这样的形式 a 1 − ( a 2 − a 3 − a 4 − . . . + a 5 + a 6... ) a1-(a2-a3-a4-...+a5+a6...) a1(a2a3a4...+a5+a6...)
使得负号变为正号,正号也可以变为负号,因此我们的正负号在选择了a1和a2后就可以任意取了,a1选最大
,a2选最小的数,那么我们通过这个方法取得其他数的绝对值,相加就是最大值

如果没有负号,那么我们只能全部相加,没有别的方法
在这里插入图片描述

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;

const int N = 1e6+5;
int a[N];
int main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0; i<n+m+1; ++i)
        cin>>a[i];
    int k = n+m+1;
    sort(a,a+k);
    LL ans  = 0 ;
    if(m==0){
        for(int i=0; i<n+m+1; ++i){
            ans += a[i];
        }
    }
    else{
       // 如果至少有一个负号
        ans = a[k-1] - a[0];
        for(int i=1; i<k-1; ++i)
            ans += abs(a[i]);
    }
    printf("%lld\n",ans);
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

葛济维的博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值