给定 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−(a2−a3−a4−...+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;
}