// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to merge alternate elements into groups
// of positive and negative
static void mergeElements(int n, List<int> arr, int[] A)
{
int i = 0;
int sum = 0;
while (i < n) {
sum = 0;
while (i < n && A[i] >= 0) {
sum += A[i];
i++;
}
if (sum > 0) {
arr.Add(sum);
}
sum = 0;
while (i < n && A[i] < 0) {
sum += A[i];
i++;
}
if (sum < 0) {
arr.Add(sum);
}
}
}
// Function to return the maximum
// after inverting at most 2 elements
static int findMaxSum(List<int> arr, int n)
{
int maxSum = 0;
int[, ] dp = new int[n, 3];
for (int i = 0; i < n; i++)
for (int j = 0; j < 3; j++)
dp[i, j] = Int32.MinValue;
dp[0, 0] = Math.Max(0, arr[0]);
dp[0, 1] = -1 * arr[0];
for (int i = 1; i < n; ++i) {
// dp[i][0] represents sum till ith index
// without inverting any element.
dp[i, 0]
= Math.Max(arr[i], dp[i - 1, 0] + arr[i]);
// dp[i][1] represents sum till ith index
// after inverting one element.
dp[i, 1] = Math.Max(0, dp[i - 1, 0]) - arr[i];
if (i >= 1) {
dp[i, 1] = Math.Max(dp[i, 1],
dp[i - 1, 1] + arr[i]);
// dp[i][2] represents sum till ith index
// after inverting two elements.
dp[i, 2] = dp[i - 1, 1] - arr[i];
}
if (i >= 2) {
dp[i, 2] = Math.Max(dp[i, 2],
dp[i - 1, 2] + arr[i]);
}
maxSum = Math.Max(maxSum, dp[i, 0]);
maxSum = Math.Max(maxSum, dp[i, 1]);
maxSum = Math.Max(maxSum, dp[i, 2]);
}
return maxSum;
}
// Driver Code
public static void Main()
{
int n = 8;
int[] A = { 2, -1, -18, 3, -1, -39, 5, -2 };
// vector 'arr' contains sum of consecutive
// positive or negative elements.
List<int> arr = new List<int>();
mergeElements(n, arr, A);
Console.WriteLine(findMaxSum(arr, arr.Count));
}
}
// This code is contributed by ukasp.