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

贪心-第十届蓝桥杯省赛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

题解:

坑 点 : 后 缀 表 达 式 可 以 通 过 调 换 前 后 顺 序 起 到 添 加 “ 括 号 ” 的 作 用 。 坑点:后缀表达式可以通过调换前后顺序起到添加“括号”的作用。

例 如 : a b − c − = a − b − c , 而 a b c − − = a − ( b − c ) = a − b + c 。 也 就 是 说 , 减 号 可 以 通 过 调 整 顺 序 转 化 为 加 号 。 例如:ab-c-=a-b-c,而abc--=a-(b-c)=a-b+c。也就是说,减号可以通过调整顺序转化为加号。 abc=abc,abc=a(bc)=ab+c

① 、 M = 0 时 , 所 有 数 直 接 相 加 即 可 , 特 判 一 下 。 ①、M=0时,所有数直接相加即可,特判一下。 M=0

② 、 M > 0 时 , 对 M 个 减 号 而 言 , 就 可 以 通 过 a − ( b − c − d − . . . ) = a − b + c + d + . . . 转 化 仅 剩 下 一 个 减 号 。 ②、M>0时,对M个减号而言,就可以通过a-(b-c-d-...)=a-b+c+d+...转化仅剩下一个减号。 M>0Ma(bcd...)=ab+c+d+...

同 样 地 , 我 们 也 可 以 将 所 有 加 号 通 过 a − ( b + c + d + . . . ) = a − b − c − d − . . . 转 化 为 减 号 。 同样地,我们也可以将所有加号通过a-(b+c+d+...)=a-b-c-d-...转化为减号。 a(b+c+d+...)=abcd...

因 此 , 除 了 第 一 个 被 减 数 a 和 减 数 b 之 间 确 定 了 一 个 ′ − ′ 号 , 剩 下 的 N + M 个 数 的 符 号 都 是 可 变 的 。 因此,除了第一个被减数a和减数b之间确定了一个'-'号,剩下的N+M个数的符号都是可变的。 abN+M

减 号 和 加 号 的 个 数 可 以 取 到 的 范 围 是 [ 1 , N + M − 1 ] 。 减号和加号的个数可以取到的范围是[1,N+M-1]。 [1,N+M1]

那 么 对 剩 下 的 N + M − 1 个 数 字 , 若 是 负 数 就 添 加 负 号 使 得 其 为 正 , 若 是 正 数 添 加 正 号 保 持 不 变 。 那么对剩下的N+M-1个数字,若是负数就添加负号使得其为正,若是正数添加正号保持不变。 N+M1使

所 以 , 我 们 现 在 仅 需 找 到 最 大 的 数 a 和 最 小 的 数 b 再 加 上 剩 下 所 有 数 的 绝 对 值 即 可 计 算 出 答 案 。 所以,我们现在仅需找到最大的数a和最小的数b再加上剩下所有数的绝对值即可计算出答案。 ab

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define inf 0x7fffffff
using namespace std;
const int N=1e5+10;
int n,m;
ll a[2*N];
ll ans;
int main()
{
    cin>>n>>m;
    ll sum=n+m+1;
    for(int i=1;i<=sum;i++)
        scanf("%lld",&a[i]);

    sort(a+1,a+sum+1);
    if(m==0)
        for(int i=1;i<=sum;i++)
            ans+=a[i];
    else
    {
        ans-=a[1];
        ans+=a[sum];
        for(int i=2;i<=sum-1;i++)
            ans+=abs(a[i]);
    }

    printf("%lld\n",ans);
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值