# Maximum Subarray Sum after inverting at most two elements

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

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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 ` `?> `

Output:

```61
```

Time Complexity :
Space Complexity :

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up