一.题目
题目描述
给定 N个加号、M 个减号以及 N+M+1个整数A1,A2,⋅⋅⋅,AN+M+1,小明想知道在所有由这 N个加号、M个减号以及 N+M+1个整数凑出的合法的后缀表达式中,结果最大的是哪一个?
请你输出这个最大的结果。
例如使用 1 2 3 + -,则 2 3 + 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
二.解释
看到题目如果有不知道后缀表达式是什么的人,可能会慌的一批,事实上这道题并不需要考虑后缀表达式的情况,只要考虑负负得正的问题。
我们来分类讨论一下:
第一种情况:全为加号,不论数据的运算顺序怎么变,结果都是一样的,所以只需要把所有的数加到一起即可;
第二种情况:此时必定有减号,以数据来分
1.所有数据都为非负数(>=0):
(1)偶数个减号,如5 + 4 + 3 - (1 - 2)= 5 + 4 + 3 + 2 - 1 = 13;
(2)奇数个减号,如5 + 4 - (1 - 2 - 3)= 5 + 4 + 3 + 2 - 1 = 13;
因此除最小的数,把剩下的数相加减去最小的数即可。
2.所有数据都为负数(< 0):
(1)偶数个减号,如 (-1) - (-2) - ((-3) + (-4) + (-5)) = 5 + 4 + 3 + 2 + (- 1) = 13;
(2)奇数个减号,如 (-1) - (-2) - (-3) - ((-4) + (-5)) = 5 + 4 + 3 + 2 + (- 1) = 13;
最后总会剩一个负数无法转化为正,所以每次都把最大的负数保留,剩下的全部取绝对值。
3.数据有正由负:
设有n个加号,m个减号
(1)当n = m = 2时, (3 + 4 + 5) - (-4) - (-2) = 5 + 4 + 3 + 2 + 1 = 15;
(2)当n = 3,m = 1时, 1 + 2 + 3 - ((-4) + (-5)) = 5 + 4 + 3 + 2 + 1 = 15;
(3)当n = 1,m = 3时, 5 - ((-4) + (-2) - 3 - 1) = 5 + 4 + 3 + 2 + 1 = 15;
所有负数最后都会转化为正数,所以把所有数据的绝对值加起来即可。
三.代码
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <cmath>
#include <string>
#include <vector>
#include <cstring>
#include <queue>
#include <unordered_map>
using namespace std;
typedef long long int64;
const int MaxN = 1e6 + 10;
int64 InN, InM, Res; //加号个数、减号个数、结果
int64 Ns[MaxN]; //保存序列的数组
unordered_map<int64, int64> Map; //计算正负数个数
int main()
{
cin >> InN >> InM;
int64 Size = InN + InM + 1;
for (int64 i = 1; i <= Size; i++)
{
scanf("%lld", Ns + i);
if (Ns[i] < 0) { Map[-1]++; }
else if (Ns[i] > 0) { Map[1]++; }
else { Map[0]++; }
}
sort(Ns + 1, Ns + Size + 1);
if (InM == 0)//没有减号的情况
{
for (int64 i = 1; i <= Size; i++) { Res += Ns[i]; }
}
else
{
if (Map[1] + Map[0] == Size)//没有负数的情况
{
for (int64 i = 2; i <= Size; i++) { Res += Ns[i]; }
Res -= Ns[1];
}
else
{
if (Map[-1] == Size)//全为负数的情况
{
for (int64 i = 1; i < Size; i++) { Res += abs(Ns[i]); }
Res += Ns[Size];
}
else//有正有负的情况
{
for (int64 i = 1; i <= Size; i++) { Res += abs(Ns[i]); }
}
}
}
cout << Res;
return 0;
}