# Maximum Subarray Sum after inverting at most two elements

Last Updated : 03 Jun, 2021

Given an array arr[] of integer elements, the task is to find maximum possible sub-array sum after changing the signs of at most two elements.
Examples:

Input: arr[] = {-5, 3, 2, 7, -8, 3, 7, -9, 10, 12, -6}
Output: 61
We can get 61 from index 0 to 10 by
changing the sign of elements at 4th and 7th indices i.e.
-8 and -9. We could have chosen -5 and -6 but this gives us
smaller sum 48.
Input: arr[] = {-5, -3, -18, 0, -4}
Output: 22

Approach: This problem can be solved using Dynamic Programming. Let’s suppose there are n elements in the array. We build our solution from smallest length to largest length.
At each step, we change the solution for length i to i+1.
For each step we have three cases:

1. (Maximum sub-array sum) by altering sign of at most 0 element.
2. (Maximum sub-array sum) by altering sign of at most 1 element.
3. (Maximum sub-array sum) by altering sign of at most 2 element.

These cases use each others previous values.

• Case 1: We have two choices either to take current element or to add current value into previous value of same case.we store whichever is larger.
• Case 2: We have two choices here
1. We alter the sign of current element and then add it to 0 or previous case 1 value. we store whichever is larger.
2. we take the current element of array and add it to previous case 2 value.If this value is larger than value we get in (a) case then we update else not.
• Case 3: We again have two choices here
1. We alter the sign of current element and add it to previous case 2 value.
2. We add current element into previous case 3 value. Larger value obtained from (a) and (b) is stored for current case.

We update the max value out of these 3 cases and store it in a variable.
For each case of each step we take Two dimensional array dp[n+1][3] if given array contains n elements.

Recurrence Relation:
Case 1: dp[i][0] = max(dp[i – 1][0] + arr[i], arr[i])
Case 2: dp[i][1] = max(max(0, dp[i – 1][0]) – arr[i], dp[i – 1][1] + arr[i])
Case 3: dp[i][2] = max(dp[i – 1][1] – arr[i], dp[i – 1][2] + arr[i])
solution = max(solution, max(dp[i][0], dp[i][1], dp[i][2]))

Below is the implementation of the above approach:

## C++

 `// C++ implementation of the approach``#include ``#include ``using` `namespace` `std;` `// Function to return the maximum required sub-array sum``int` `maxSum(``int` `a[], ``int` `n)``{``    ``int` `ans = 0;``    ``int``* arr = ``new` `int``[n + 1];` `    ``// Creating one based indexing``    ``for` `(``int` `i = 1; i <= n; i++)``        ``arr[i] = a[i - 1];` `    ``// 2d array to contain solution for each step``    ``int``** dp = ``new` `int``*[n + 1];``    ``for` `(``int` `i = 0; i <= n; i++)``        ``dp[i] = ``new` `int``[3];``    ``for` `(``int` `i = 1; i <= n; ++i) {` `        ``// Case 1: Choosing current or (current + previous)``        ``// whichever is smaller``        ``dp[i][0] = max(arr[i], dp[i - 1][0] + arr[i]);` `        ``// Case 2:(a) Altering sign and add to previous case 1 or``        ``// value 0``        ``dp[i][1] = max(0, dp[i - 1][0]) - arr[i];` `        ``// Case 2:(b) Adding current element with previous case 2``        ``// and updating the maximum``        ``if` `(i >= 2)``            ``dp[i][1] = max(dp[i][1], dp[i - 1][1] + arr[i]);` `        ``// Case 3:(a) Altering sign and add to previous case 2``        ``if` `(i >= 2)``            ``dp[i][2] = dp[i - 1][1] - arr[i];` `        ``// Case 3:(b) Adding current element with previous case 3``        ``if` `(i >= 3)``            ``dp[i][2] = max(dp[i][2], dp[i - 1][2] + arr[i]);` `        ``// Updating the maximum value of variable ans``        ``ans = max(ans, dp[i][0]);``        ``ans = max(ans, dp[i][1]);``        ``ans = max(ans, dp[i][2]);``    ``}` `    ``// Return the final solution``    ``return` `ans;``}` `// Driver code``int` `main()``{``    ``int` `arr[] = { -5, 3, 2, 7, -8, 3, 7, -9, 10, 12, -6 };``    ``int` `n = ``sizeof``(arr) / ``sizeof``(arr[0]);``    ``cout << maxSum(arr, n);` `    ``return` `0;``}`

## Java

 `// Java implementation of the approach` `class` `GFG``{``    ``// Function to return the maximum required sub-array sum``    ``static` `int` `maxSum(``int` `[]a, ``int` `n)``    ``{``        ``int` `ans = ``0``;``        ``int` `[] arr = ``new` `int``[n + ``1``];``    ` `        ``// Creating one based indexing``        ``for` `(``int` `i = ``1``; i <= n; i++)``            ``arr[i] = a[i - ``1``];``    ` `        ``// 2d array to contain solution for each step``        ``int` `[][] dp = ``new` `int` `[n + ``1``][``3``];``        ``for` `(``int` `i = ``1``; i <= n; ++i) ``        ``{``    ` `            ``// Case 1: Choosing current or (current + previous)``            ``// whichever is smaller``            ``dp[i][``0``] = Math.max(arr[i], dp[i - ``1``][``0``] + arr[i]);``    ` `            ``// Case 2:(a) Altering sign and add to previous case 1 or``            ``// value 0``            ``dp[i][``1``] = Math.max(``0``, dp[i - ``1``][``0``]) - arr[i];``    ` `            ``// Case 2:(b) Adding current element with previous case 2``            ``// and updating the maximum``            ``if` `(i >= ``2``)``                ``dp[i][``1``] = Math.max(dp[i][``1``], dp[i - ``1``][``1``] + arr[i]);``    ` `            ``// Case 3:(a) Altering sign and add to previous case 2``            ``if` `(i >= ``2``)``                ``dp[i][``2``] = dp[i - ``1``][``1``] - arr[i];``    ` `            ``// Case 3:(b) Adding current element with previous case 3``            ``if` `(i >= ``3``)``                ``dp[i][``2``] = Math.max(dp[i][``2``], dp[i - ``1``][``2``] + arr[i]);``    ` `            ``// Updating the maximum value of variable ans``            ``ans = Math.max(ans, dp[i][``0``]);``            ``ans = Math.max(ans, dp[i][``1``]);``            ``ans = Math.max(ans, dp[i][``2``]);``        ``}``    ` `        ``// Return the final solution``        ``return` `ans;``    ``}``    ` `    ``// Driver code``    ``public` `static` `void` `main (String[] args) ``    ``{``        ``int` `arr[] = { -``5``, ``3``, ``2``, ``7``, -``8``, ``3``, ``7``, -``9``, ``10``, ``12``, -``6` `};``        ``int` `n = arr.length;``        ``System.out.println(maxSum(arr, n));``    ``}``}` `// This code is contributed by ihritik`

## Python3

 `# Python3 implementation of the approach ` `# Function to return the maximum ``# required sub-array sum ``def` `maxSum(a, n): ` `    ``ans ``=` `0``    ``arr ``=` `[``0``] ``*` `(n ``+` `1``)``    ` `    ``# Creating one based indexing``    ``for` `i ``in` `range``(``1``, n ``+` `1``):``        ``arr[i] ``=` `a[i ``-` `1``]` `    ``# 2d array to contain solution for each step ``    ``dp ``=` `[[``0` `for` `i ``in` `range``(``3``)] ``             ``for` `j ``in` `range``(n ``+` `1``)] ``    ``for` `i ``in` `range``(``0``, n ``+` `1``): ``        ` `        ``# Case 1: Choosing current or ``        ``# (current + previous) whichever is smaller ``        ``dp[i][``0``] ``=` `max``(arr[i], dp[i ``-` `1``][``0``] ``+` `arr[i]) ` `        ``# Case 2:(a) Altering sign and add to ``        ``# previous case 1 or value 0 ``        ``dp[i][``1``] ``=` `max``(``0``, dp[i ``-` `1``][``0``]) ``-` `arr[i] ` `        ``# Case 2:(b) Adding current element with ``        ``# previous case 2 and updating the maximum ``        ``if` `i >``=` `2``: ``            ``dp[i][``1``] ``=` `max``(dp[i][``1``],``                           ``dp[i ``-` `1``][``1``] ``+` `arr[i]) ` `        ``# Case 3:(a) Altering sign and ``        ``# add to previous case 2 ``        ``if` `i >``=` `2``: ``            ``dp[i][``2``] ``=` `dp[i ``-` `1``][``1``] ``-` `arr[i] ` `        ``# Case 3:(b) Adding current element``        ``# with previous case 3 ``        ``if` `i >``=` `3``: ``            ``dp[i][``2``] ``=` `max``(dp[i][``2``], ``                           ``dp[i ``-` `1``][``2``] ``+` `arr[i]) ` `        ``# Updating the maximum value``        ``# of variable ans ``        ``ans ``=` `max``(ans, dp[i][``0``]) ``        ``ans ``=` `max``(ans, dp[i][``1``]) ``        ``ans ``=` `max``(ans, dp[i][``2``]) ``    ` `    ``# Return the final solution ``    ``return` `ans ` `# Driver code ``if` `__name__ ``=``=` `"__main__"``:` `    ``arr ``=` `[``-``5``, ``3``, ``2``, ``7``, ``-``8``, ``3``, ``            ``7``, ``-``9``, ``10``, ``12``, ``-``6``] ``    ``n ``=` `len``(arr) ``    ``print``(maxSum(arr, n)) ` `# This code is contributed by Rituraj Jain`

## C#

 `// C# implementation of the approach``using` `System;` `class` `GFG``{``    ``// Function to return the maximum required sub-array sum``    ``static` `int` `maxSum(``int` `[] a, ``int` `n)``    ``{``        ``int` `ans = 0;``        ``int` `[] arr = ``new` `int``[n + 1];``    ` `        ``// Creating one based indexing``        ``for` `(``int` `i = 1; i <= n; i++)``            ``arr[i] = a[i - 1];``    ` `        ``// 2d array to contain solution for each step``        ``int` `[, ] dp = ``new` `int` `[n + 1, 3];``        ``for` `(``int` `i = 1; i <= n; ++i) ``        ``{``    ` `            ``// Case 1: Choosing current or (current + previous)``            ``// whichever is smaller``            ``dp[i, 0] = Math.Max(arr[i], dp[i - 1, 0] + arr[i]);``    ` `            ``// Case 2:(a) Altering sign and add to previous case 1 or``            ``// value 0``            ``dp[i, 1] = Math.Max(0, dp[i - 1, 0]) - arr[i];``    ` `            ``// Case 2:(b) Adding current element with previous case 2``            ``// and updating the maximum``            ``if` `(i >= 2)``                ``dp[i, 1] = Math.Max(dp[i, 1], dp[i - 1, 1] + arr[i]);``    ` `            ``// Case 3:(a) Altering sign and add to previous case 2``            ``if` `(i >= 2)``                ``dp[i, 2] = dp[i - 1, 1] - arr[i];``    ` `            ``// Case 3:(b) Adding current element with previous case 3``            ``if` `(i >= 3)``                ``dp[i, 2] = Math.Max(dp[i, 2], dp[i - 1, 2] + arr[i]);``    ` `            ``// Updating the maximum value of variable ans``            ``ans = Math.Max(ans, dp[i, 0]);``            ``ans = Math.Max(ans, dp[i, 1]);``            ``ans = Math.Max(ans, dp[i, 2]);``        ``}``    ` `        ``// Return the final solution``        ``return` `ans;``    ``}``    ` `    ``// Driver code``    ``public` `static` `void` `Main ()``    ``{``        ``int` `[] arr = { -5, 3, 2, 7, -8, 3, 7, -9, 10, 12, -6 };``        ``int` `n = arr.Length;``        ``Console.WriteLine(maxSum(arr, n));``    ``}``}` `// This code is contributed by ihritik`

## PHP

 `= 2) ``            ``\$dp``[``\$i``][1] = max(``\$dp``[``\$i``][1], ``                             ``\$dp``[``\$i` `- 1][1] + ``\$arr``[``\$i``]); ` `        ``// Case 3:(a) Altering sign and ``        ``// add to previous case 2 ``        ``if` `(``\$i` `>= 2) ``            ``\$dp``[``\$i``][2] = ``\$dp``[``\$i` `- 1][1] - ``\$arr``[``\$i``]; ` `        ``// Case 3:(b) Adding current element ``        ``// with previous case 3 ``        ``if` `(``\$i` `>= 3) ``            ``\$dp``[``\$i``][2] = max(``\$dp``[``\$i``][2],``                             ``\$dp``[``\$i` `- 1][2] + ``\$arr``[``\$i``]); ` `        ``// Updating the maximum value of variable ans ``        ``\$ans` `= max(``\$ans``, ``\$dp``[``\$i``][0]); ``        ``\$ans` `= max(``\$ans``, ``\$dp``[``\$i``][1]); ``        ``\$ans` `= max(``\$ans``, ``\$dp``[``\$i``][2]); ``    ``} ` `    ``// Return the final solution ``    ``return` `\$ans``; ``} ` `// Driver code ``\$arr` `= ``array``( -5, 3, 2, 7, -8, 3, ``               ``7, -9, 10, 12, -6 ); ``\$n` `= ``count``(``\$arr``) ; ` `echo` `maxSum(``\$arr``, ``\$n``); ` `// This code is contributed by Ryuga``?>`

## Javascript

 ``

Output:
`61`

Time Complexity :
Space Complexity :

Article Tags :
Practice Tags :