三种情况:
(1),负号个数为零,直接全加起来
(2),负号个数小于等于负数个数:
假设a[1:k]是负数,a[k+1:n+m+1]是正数,m<=k。
总可以化为 -(a[1]+a[2]+..a[i])-(a[i]+a[i+1]..a[j])-....-(a[z]+a[z+1]...+a[k]);(i<j<z<k);
这样所有负数都可变为正数,但是有一个特殊,就是所有数都是负数,那么最大的那个负数是不能改变的
(3),负号个数大于负数个数:
还是(2)的假设的前提下用k-1个负号将k-1个负数变正数,拿出一个负数x来做一个如下组合:
-(x-a[i]-a[i+1]-...a[j]),其中a[i],a[i+1]...a[j]均为正数,这样就实现了x变为正数,正数还是正数的目的。
但是有一个特殊情况就是负数个数为0时,x就必须取最小的正数了。
#include <iostream>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <cstdio>
#include <string>
#include <stack>
#include <set>
#define IOS ios::sync_with_stdio(false), cin.tie(0)
using namespace std;
typedef long long ll;
const double eps=1e-6;
ll a[200010];
int main()
{
IOS;
ll n,m;
cin>>n>>m;
ll cnt=0;//负数个数
for(int i=1;i<=n+m+1;i++){
cin>>a[i];
if(a[i]<0)cnt++;
}
sort(a+1,a+1+n+m+1);
ll ans=0;
if(m==0){//符号个数为0
for(int i=1;i<=n+m+1;i++){
ans+=a[i];
}
cout<<ans<<endl;
}
else if(cnt>=m){//负数多于负号
for(int i=1;i<n+m+1;i++){
ans+=abs(a[i]);
}
ans+=a[n+m+1];//这一句防止最大的数是负数的情况
cout<<ans<<endl;
}
else {//负号个数多于负数个数
for(int i=1;i<=n+m+1;i++){
ans+=abs(a[i]);
}
if(cnt==0){//如果全是正数
ans-=2*a[1];
}
cout<<ans<<endl;
}
getchar();
return 0;
}