D. Slime
There are nn slimes in a row. Each slime has an integer value (possibly negative or zero) associated with it.
Any slime can eat its adjacent slime (the closest slime to its left or to its right, assuming that this slime exists).
When a slime with a value xx eats a slime with a value yy, the eaten slime disappears, and the value of the remaining slime changes to x−yx−y.
The slimes will eat each other until there is only one slime left.
Find the maximum possible value of the last slime.
Input
The first line of the input contains an integer nn (1≤n≤5000001≤n≤500000) denoting the number of slimes.
The next line contains nn integers aiai (−109≤ai≤109−109≤ai≤109), where aiai is the value of ii-th slime.
Output
Print an only integer — the maximum possible value of the last slime.
Examples
input
Copy
4 2 1 2 1
output
Copy
4
input
Copy
5 0 -1 -1 -1 -1
output
Copy
4
题意:给你n个数,任意相邻两数作差x=a[i]-a[j],只要i!=j即可作差,所得x将代替原来的a[i],a[j],最终会剩下一个数,问你这个数最大是多少?
思路:一开始以为是dp,推了几组数据发现有规律的。
我们可以分为三类:全是正数,全是负数,正负都有。
对于1,2,3,4,我们推一下会发现,无论怎么排列这几个数,最终都能求得最大值8.
1.所以如果整个数组都是正号的,直接排序,让x=a[1]-a[2]构造一个负数,接下来x=x-a[j](j>=3&&j<n)积累这个差,会积累到一个特别小的负数,用a[n]-x即为最大值。整个数组负号的可以全变正号,直接用上面的方法。
2.对于异号的数组,依然排序,找到最大的负数,即从右向左查,出现的第一个负数x,位置pos。由于x的右边全是正数,那么继x=x-a[j],去积累差,最后x=a[n]-x,得到目前最大。接下来用x直接减去pos以左的全部负数,即得最大值。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll a[500050],n;
int main()
{
while(~scanf("%lld",&n))
{
for(ll i=1;i<=n;i++)scanf("%lld",&a[i]);
if(n==1){printf("%lld\n",a[1]);continue;}
sort(a+1,a+n+1);
ll f1,f2,sum;
f1=f2=0;
for(ll i=1;i<=n;i++)
{
if(a[i]>=0)f1=1; //代表有正数和0
if(a[i]<0)f2=1; //代表有负数
}
if(f1&&f2==0) //只有正数时
{
sum=a[1];
for(ll i=2;i<=n;i++)
{
sum=sum-a[i]; //积累差
}
sum=-sum;
}
else if(f1==0&&f2) //只有负数时
{
for(ll i=1;i<=n;i++)a[i]=-a[i];
sort(a+1,a+n+1);
sum=a[1];
for(ll i=2;i<=n;i++)
{
sum=sum-a[i];
}
sum=-sum;
}
else
{
ll pos;
for(ll i=n;i>=1;i--) //找到右边第一个负数pos
{
if(a[i]<=0)
{
pos=i;
break;
}
}
sum=a[pos];
for(ll i=pos+1;i<=n;i++)
{
sum=sum-a[i]; //积累差
}
sum=-sum;
for(ll i=1;i<pos;i++)sum-=a[i]; //向左积累回去
}
printf("%lld\n",sum);
}
return 0;
}