后缀表达式

给定 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, · · · , A(N+M+1).

输出格式:

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

输入样例:

1 1
1 2 3

输出样例:

4

数据范围:

对于所有评测用例,0 ≤ N, M ≤ 100000, -10^9 ≤ Ai ≤ 10^9。


解题思路

我们需要讨论负数的个数和 M 的关系:
1、给定的数字本身中负数的个数等于 M,那么显而易见把所有的负数配合负号全部变为正数。
2、给定的数字本身中负数的个数小于 M,这种情况下要分两种小情况进行考虑。
(1)当全部是正数,那么把 M-1 个负号变成正号,减掉最小的数,然后相加其它数。
(2)当既有正数又有负数,那么可以通过转换变成所有数的绝对值相加。

例:输入2 4
-1 -2 -3 4 5 6 7
可以这样组合:4-((-3)-7-2)+5+6 -(-1)

3、给定的数字本身中负数的个数大于 M,这种情况下要分两种小情况进行考虑。
(1)当没有正数全部为负数时,那么减去一个绝对值最小的数,其他数字绝对值相加。

例: 输入 : 1 2
-2 -3 -1 -5
可以这样组合: (-1) - (-5)-((-3)+(-2))

(2)当存在正数和负数时,那么所有数字的绝对值相加。

比如(6 5 -4 -3 -2 -1),有1个减号,那么可以变成 6 + 5 - ( -4 + -3 + -2 + -1 )
;有2个减号,那么可以变成 6 + 5 - -4 - ( -3 + -2 + -1 ) ;有3个减号,那么可以变成6 + 5 - -4 -
-3 - ( -2 + -1 )

(3)当负号 M = 0 时,那么只能所有数相加了。


源代码:

#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 200005
int a[maxn];
int main()
{
	int n, m, item = 0;
	long long ans = 0;
	cin >> n >> m;
	for (int i = 0; i < n + m + 1; i++)
	{
		cin >> a[i];
	}
	sort(a, a + n + m + 1);
	for (int i = 0; i < n + m + 1; i++)
	{
		if (a[i] > 0)
		{
			item = i;
			break;
		}
	}
	if (a[n + m] <= 0)
		item = m + n + 1;
	if (item >= m && m > 0)
	{
		if (item == m + n + 1)
		{
			a[item - 1] = -a[item - 1];
		}
		for (int i = 0; i < item; i++)
		{
			a[i] = -a[i];
		}
	}
	else
	{
		if (item == 0)
		{
			ans = -(2 * a[item]);
		}
		else
		{
			for (int i = 0; i < item; i++)
				a[i] = -a[i];
		}
		m = m - item;
		n = n + item;
	}
	for (int i = 0; i < n + m + 1; i++)
	{
		ans += a[i];
	}
	printf("%lld", ans);
	return 0;
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值