Codeforces 1038D - Slime(贪心)

在这里插入图片描述

题目大意:

给出 n 个史莱姆,每个可以吞噬左边或右边的,然后他的数值变为x- y,询问最终史莱姆的最大值。

解题思路:

如果这些数有正有负,则可以利用负数 - 正数 ,使最后只留下一个正数,再利用正数 - 负数 = 正数 + abs(num),所以有正有负时,输出和的绝对值即可。
如果这些数全正或全负,则最后的值是Σ|a[i]| - min(a[i]) * 2,可以这样想,假设有5个正数 a b c d e 他们的和的绝对值是 sum,我们找出一个最小的数(假设是a)然后吞噬旁边的数,得到非正数(a - b)这样就可以构造有正有负的序列了,所以这个序列的值为 b + c + d + b - a,而总和是sum,则sum - 2min(|a[i]|)就是最后的答案(负数同理,利用a - b 构造非负数即可)。

Code:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
const int mod = 1e9 + 7;
const int N = 5e5 + 50;
const int inf = 0x3f3f3f3f;
typedef long long ll;
typedef pair<int, int> pii;
ll a[N];
int main()
{
	ll sum = 0, m = 0x7fffffff;
	int z = 0, f = 0;
	int n;
	cin >> n;
	for (int i = 1; i <= n; i ++)
	{
		cin >> a[i];
		sum += abs(a[i]);
		m = min(m, abs(a[i]));
		if (a[i] > 0)
		  z++;
		else if (a[i] < 0)
		  f++;
	}
	if (n == 1)
	{
		cout << a[1] << endl;
		return 0;
	}
	if (z && f)
	  cout << sum << endl;
	else
	  cout << sum - 2 * m << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/aezakmias/article/details/107590419
今日推荐