📌  相关文章
📜  将前缀和后缀乘以-1后,最大化数组的总和(1)

📅  最后修改于: 2023-12-03 15:25:16.866000             🧑  作者: Mango

将前缀和后缀乘以-1后,最大化数组的总和

介绍

给定一个整数数组,可以对其前缀和和后缀和分别乘以-1,需要求得最终数组总和的最大值。

这是一道典型的贪心问题,思路是将整个数组分成三部分:前缀、中间部分、后缀。对于前缀和和后缀和,我们需要将其乘以-1,使得它们对总和的贡献变成负数。因此,我们需要找到最小的前缀和和最小的后缀和,将它们分别乘以-1。而对于中间部分,由于没有限制,我们可以随便处理,比如不处理、全部取反都可以。

步骤
  1. 首先计算前缀和和后缀和,并记录下它们的最小值。
  2. 将前缀和和后缀和乘以-1。
  3. 通过贪心策略,对中间部分进行处理,可以随意取反或不取反。
  4. 计算最终数组的总和。
代码

以下是一个C++实现的代码片段:

#include <bits/stdc++.h>

using namespace std;

const int N = 100010;

int a[N], s[N];

int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++ ) {
        scanf("%d", &a[i]);
        s[i] = s[i - 1] + a[i];
    }

    int ans = -0x3f3f3f3f, min_prefix = 0, min_suffix = 0, prefix_sum = 0;
    for (int i = 0; i < n; i ++ ) {
        ans = max(ans, s[i] + prefix_sum - min_prefix);
        min_prefix = min(min_prefix, s[i] + prefix_sum);
        prefix_sum += a[i + 1];
    }

    int suffix_sum = 0;
    for (int i = n; i; i -- ) {
        ans = max(ans, suffix_sum + s[n] - s[i - 1] - min_suffix);
        min_suffix = min(min_suffix, suffix_sum + s[n] - s[i - 1]);
        suffix_sum += a[i - 1];
    }

    printf("%d\n", ans);

    return 0;
}

该代码以前缀和作为例子,后缀和处理方法与之类似。在代码实现中 prefix_sumsuffix_sum 分别表示前缀和和后缀和的累计和。将前缀和或后缀和乘以-1的方法也十分简单,只需要在计算前缀和或后缀和时取相反数即可。