cf 508div2 D题 slime

版权声明:那个,最起码帮我加点人气吧,署个名总行吧 https://blog.csdn.net/qq_41670466/article/details/82526680

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.

题意大致就是给你一行数,这行数正负数都有,然后每一个数x都可以吃掉它附近的数y,被吃掉的数y会消失,之前的数x则变成x-y,这行数最后只能剩下一个数,问这个数最后最大是多少?

思路:从题目中给出的数据可以看出对于数的正负性不同,处理方法是不一样的,对于全正或者全负,处理方法是:先找出这一样数中绝对值最小的数,然后把剩余的数字按照绝对值相加,最后再减去那个最小值,原因是:(用全为正数来说)很显然如果你在处理过程中,每一个数都是正值,那么整个数一定是减少的,比如 2 1 2 1,如果你让2-1得1 2 1 然后再让2 -1的 1 1 最后结果是为0的,那么很显然只有让这一行数中出现负数然后再去相减才能得到更大的数,那么这个问题就转化为如何让这个负数最大,于是可以想到让一个最小的数减去它周围的数会在一开始就得到一个最大的负数(是相对于第一步来说),然后就是负数减去正数,这样的话负数的绝对值一直在增加,然后让最后剩下的整数去减这个负数就得到最大的数。而对于负正都有的那种,只需要让他们绝对值相加就好,原因是:对于正负皆有的那种,就没有什么得到一个最大的绝对值负数。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[500010];

int main()
{
	int n;
	ll ans = 0;
	int flag = 0;
	ll mn = 0x3f3f3f3f;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		//scanf("%lld", &a[i]);
		cin >> a[i];
		ans += abs(a[i]);
		if (a[i] > 0) flag |= 1;
		if (a[i] < 0) flag |= 2;
		mn = min(mn, abs(a[i]));
	}
	if (n == 1) printf("%d\n", a[1]);
	else
	{
		ans = flag == 3 ? ans : ans - 2 * mn;
		//printf("%lld\n", ans);
		cout << ans << endl;
	}
	//system("pause");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41670466/article/details/82526680
今日推荐