GFG App
Open App
Browser
Continue

# Maximum sum of at most K non-overlapping Subarray

Given an array, arr[] of size N, the task is to find the sum of the at most K non-overlapping contiguous subarray within an arr[] with the maximum sum.

Examples:

Input: arr[] = [4, 1, -3, 7, -5, 6, -2, 1], K = 3
Output: 18
Explanation: In the above input, the maximum k subarray sum is 18 and the subarrays are {{4, 1}, {7}, {6}}

Input: arr[] = [8, -1, 4, 2, 6, -6, 4, -1], K = 2
Output: 23
Explanation: In the above input, the maximum k subarray sum is 23 and the subarrays are {{8, -1, 4, 2, 6}, {4}}

Approach: This can be solved with the following idea:

Calculating the prefix sum will let us know about the previous maximum element. At, each point see whether to exclude the element or include the element.

Below are the steps involved in the implementation of the code:

• Take an array pre_sum[] of size N + 1(N is the size of array arr[]).
• Initialise pre_sum[0] = 0 and store prefix sum of array arr[] in pre_sum[] array from index 1 ≤ i ≤ N.
• Let i be the index we are at, j be the total transaction remaining, b represent if we want to start from this index(1 for buying and 0 for selling), and pre_sum[] represents the sum of the array.
• Transitions:
• dp[i][j][1] = max(-A[i] + dp[j][i + 1][0], dp[j][i + 1][1])
• dp[i][j][0] = max(A[i] + dp[j – 1][i + 1][1], dp[j][i + 1][0])

Below is the Implementation of the above approach:

## C++

 `// C++ program to find out the maximum` `// sum of at most K non-overlapping` `// subarray` `#include ` `using` `namespace` `std;`   `int` `B;` `vector<``int``> pre_sum;` `int` `dp[501][201][2];` `int` `solve(``int` `j, ``int` `i, ``int` `b)` `{`   `    ``// If the result has already been` `    ``// calculated return that result` `    ``if` `(dp[i][j][b] != -1)` `        ``return` `dp[i][j][b];`   `    ``// If i has reached the end of the` `    ``// array return 0` `    ``if` `(i == B)` `        ``return` `0;`   `    ``// If we have exhausted the number of` `    ``// transaction return 0` `    ``if` `(j == 0)` `        ``return` `0;`   `    ``int` `res;` `    ``if` `(b == 1)` `        ``res = max(-pre_sum[i] + solve(j, i + 1, 0),` `                  ``solve(j, i + 1, 1));`   `    ``else` `        ``res = max(pre_sum[i] + solve(j - 1, i + 1, 1),` `                  ``solve(j, i + 1, 0));`   `    ``// Return the result` `    ``return` `dp[i][j][b] = res;` `}`   `int` `maxSum(``int` `K, ``int` `N, ``int` `arr[])` `{` `    ``pre_sum = vector<``int``>(N + 1, 0);`   `    ``// Finding prefix sum of array arr[]` `    ``for` `(``int` `i = 1; i <= N; i++)` `        ``pre_sum[i] = pre_sum[i - 1] + arr[i - 1];`   `    ``// Initializing DP with -1` `    ``memset``(dp, -1, ``sizeof``(dp));`   `    ``// Copying n to global B` `    ``B = N + 1;`   `    ``// Function to find maximum` `    ``return` `solve(K, 0, 1);` `}`   `// Driver code` `int` `main()` `{`   `    ``// Test case 1` `    ``int` `arr1[] = { 4, 1, -3, 7, -5, 6, -2, 1 };` `    ``int` `K1 = 3;` `    ``int` `N1 = ``sizeof``(arr1) / ``sizeof``(arr1[0]);`   `    ``// Function call` `    ``cout << maxSum(K1, N1, arr1) << endl;`   `    ``// Test case 2` `    ``int` `arr2[] = { 8, -1, 4, 2, 6, -6, 4, -1 };` `    ``int` `K2 = 2;` `    ``int` `N2 = ``sizeof``(arr2) / ``sizeof``(arr2[0]);`   `    ``// Function call` `    ``cout << maxSum(K2, N2, arr2);` `    ``return` `0;` `}`

## Java

 `// Java program to find out the maximum` `// sum of at most K non-overlapping` `// subarray` `import` `java.util.*;`   `class` `GFG {` `  ``static` `int` `B;` `  ``static` `int``[][][] dp = ``new` `int``[``501``][``201``][``2``];` `  ``static` `List pre_sum = ``new` `ArrayList<>();`   `  ``public` `static` `int` `solve(``int` `j, ``int` `i, ``int` `b, ``int``[] arr)` `  ``{`   `    ``// If the result has already been` `    ``// calculated return that result` `    ``if` `(dp[i][j][b] != -``1``)` `      ``return` `dp[i][j][b];`   `    ``// If i has reached the end of the` `    ``// array return 0` `    ``if` `(i == B)` `      ``return` `0``;`   `    ``// If we have exhausted the number of` `    ``// transaction return 0` `    ``if` `(j == ``0``)` `      ``return` `0``;`   `    ``int` `res;` `    ``if` `(b == ``1``)` `      ``res = Math.max(-pre_sum.get(i)` `                     ``+ solve(j, i + ``1``, ``0``, arr),` `                     ``solve(j, i + ``1``, ``1``, arr));` `    ``else` `      ``res = Math.max(` `      ``pre_sum.get(i)` `      ``+ solve(j - ``1``, i + ``1``, ``1``, arr),` `      ``solve(j, i + ``1``, ``0``, arr));`   `    ``// Return the result` `    ``return` `dp[i][j][b] = res;` `  ``}`   `  ``public` `static` `int` `maxSum(``int` `K, ``int` `N, ``int``[] arr)` `  ``{` `    ``pre_sum = ``new` `ArrayList<>(` `      ``Collections.nCopies(N + ``1``, ``0``));`   `    ``// Finding prefix sum of array arr[]` `    ``for` `(``int` `i = ``1``; i <= N; i++)` `      ``pre_sum.set(i, pre_sum.get(i - ``1``) + arr[i - ``1``]);`   `    ``// Initializing DP with -1` `    ``for` `(``int``[][] row : dp)` `      ``for` `(``int``[] rowColumn : row)` `        ``Arrays.fill(rowColumn, -``1``);`   `    ``// Copying n to global B` `    ``B = N + ``1``;`   `    ``// Function to find maximum` `    ``return` `solve(K, ``0``, ``1``, arr);` `  ``}`   `  ``// Driver code` `  ``public` `static` `void` `main(String[] args)` `  ``{`   `    ``// Test case 1` `    ``int``[] arr1 = { ``4``, ``1``, -``3``, ``7``, -``5``, ``6``, -``2``, ``1` `};` `    ``int` `K1 = ``3``;` `    ``int` `N1 = arr1.length;`   `    ``// Function call` `    ``System.out.println(maxSum(K1, N1, arr1));`   `    ``// Test case 2` `    ``int``[] arr2 = { ``8``, -``1``, ``4``, ``2``, ``6``, -``6``, ``4``, -``1` `};` `    ``int` `K2 = ``2``;` `    ``int` `N2 = arr2.length;`   `    ``// Function call` `    ``System.out.println(maxSum(K2, N2, arr2));` `  ``}` `}`   `// This code is contributed by Prasad Kandekar(prasad264)`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `public` `class` `GFG {` `  ``static` `int` `B;` `  ``static` `int``[, , ] dp = ``new` `int``[501, 201, 2];` `  ``static` `List<``int``> pre_sum = ``new` `List<``int``>();`   `  ``public` `static` `int` `solve(``int` `j, ``int` `i, ``int` `b, ``int``[] arr)` `  ``{`   `    ``// If the result has already been` `    ``// calculated return that result` `    ``if` `(dp[i, j, b] != -1)` `      ``return` `dp[i, j, b];`   `    ``// If i has reached the end of the` `    ``// array return 0` `    ``if` `(i == B)` `      ``return` `0;`   `    ``// If we have exhausted the number of` `    ``// transaction return 0` `    ``if` `(j == 0)` `      ``return` `0;`   `    ``int` `res;` `    ``if` `(b == 1)` `      ``res = Math.Max(-pre_sum[i]` `                     ``+ solve(j, i + 1, 0, arr),` `                     ``solve(j, i + 1, 1, arr));` `    ``else` `      ``res = Math.Max(` `      ``pre_sum[i] + solve(j - 1, i + 1, 1, arr),` `      ``solve(j, i + 1, 0, arr));`   `    ``// Return the result` `    ``return` `dp[i, j, b] = res;` `  ``}`   `  ``public` `static` `int` `maxSum(``int` `K, ``int` `N, ``int``[] arr)` `  ``{` `    ``for` `(``int` `i = 0; i < N + 1; i++) {` `      ``pre_sum.Add(0);` `    ``}`   `    ``// Finding prefix sum of array arr[]` `    ``for` `(``int` `i = 1; i <= N; i++)` `      ``pre_sum[i] = pre_sum[i - 1] + arr[i - 1];`   `    ``// Initializing DP with -1` `    ``for` `(``int` `i = 0; i < 501; i++) {` `      ``for` `(``int` `j = 0; j < 201; j++) {` `        ``dp[i, j, 0] = dp[i, j, 1] = -1;` `      ``}` `    ``}`   `    ``// Copying n to global B` `    ``B = N + 1;`   `    ``// Function to find maximum` `    ``return` `solve(K, 0, 1, arr);` `  ``}`   `  ``// Driver code` `  ``static` `public` `void` `Main()` `  ``{`   `    ``// Test case 1` `    ``int``[] arr1 = { 4, 1, -3, 7, -5, 6, -2, 1 };` `    ``int` `K1 = 3;` `    ``int` `N1 = arr1.Length;`   `    ``// Function call` `    ``Console.WriteLine(maxSum(K1, N1, arr1));`   `    ``// Test case 2` `    ``int``[] arr2 = { 8, -1, 4, 2, 6, -6, 4, -1 };` `    ``int` `K2 = 2;` `    ``int` `N2 = arr2.Length;`   `    ``// Function call` `    ``Console.WriteLine(maxSum(K2, N2, arr2));` `  ``}` `}`   `// This code is contributed by Rohit Pradhan`

## Python3

 `import` `math`   `B ``=` `0` `dp ``=` `[[[``0` `for` `_ ``in` `range``(``2``)] ``for` `_ ``in` `range``(``201``)] ``for` `_ ``in` `range``(``501``)]` `pre_sum ``=` `[]`   `def` `solve(j, i, b, arr):` `    ``global` `dp, pre_sum`   `    ``# If the result has already been calculated, return that result` `    ``if` `dp[i][j][b] !``=` `0``:` `        ``return` `dp[i][j][b]`   `    ``# If i has reached the end of the array, return 0` `    ``if` `i ``=``=` `B:` `        ``return` `0`   `    ``# If we have exhausted the number of transactions, return 0` `    ``if` `j ``=``=` `0``:` `        ``return` `0`   `    ``res ``=` `0` `    ``if` `b ``=``=` `1``:` `        ``res ``=` `max``(``-``pre_sum[i] ``+` `solve(j, i ``+` `1``, ``0``, arr), solve(j, i ``+` `1``, ``1``, arr))` `    ``else``:` `        ``res ``=` `max``(pre_sum[i] ``+` `solve(j ``-` `1``, i ``+` `1``, ``1``, arr), solve(j, i ``+` `1``, ``0``, arr))`   `    ``# Return the result` `    ``dp[i][j][b] ``=` `res` `    ``return` `res`   `def` `maxSum(K, N, arr):` `    ``global` `B, dp, pre_sum`   `    ``pre_sum ``=` `[``0``] ``*` `(N ``+` `1``)`   `    ``# Finding prefix sum of array arr[]` `    ``for` `i ``in` `range``(``1``, N ``+` `1``):` `        ``pre_sum[i] ``=` `pre_sum[i ``-` `1``] ``+` `arr[i ``-` `1``]`   `    ``# Initializing DP with 0` `    ``dp ``=` `[[[``0` `for` `_ ``in` `range``(``2``)] ``for` `_ ``in` `range``(``201``)] ``for` `_ ``in` `range``(``501``)]`   `    ``# Copying n to global B` `    ``B ``=` `N ``+` `1`   `    ``# Function to find maximum` `    ``return` `solve(K, ``0``, ``1``, arr)`   `# Driver code` `if` `__name__ ``=``=` `'__main__'``:` `    ``# Test case 1` `    ``arr1 ``=` `[``4``, ``1``, ``-``3``, ``7``, ``-``5``, ``6``, ``-``2``, ``1``]` `    ``K1 ``=` `3` `    ``N1 ``=` `len``(arr1)`   `    ``# Function call` `    ``print``(maxSum(K1, N1, arr1))`   `    ``# Test case 2` `    ``arr2 ``=` `[``8``, ``-``1``, ``4``, ``2``, ``6``, ``-``6``, ``4``, ``-``1``]` `    ``K2 ``=` `2` `    ``N2 ``=` `len``(arr2)`   `    ``# Function call` `    ``print``(maxSum(K2, N2, arr2))`

## Javascript

 `let B;` `let dp = Array.from(Array(501), () =>` `Array.from(Array(201), () => ``new` `Array(2).fill(-1))` `);` `let pre_sum = [];`   `function` `solve(j, i, b, arr) {` `// If the result has already been` `// calculated return that result` `if` `(dp[i][j][b] !== -1) ``return` `dp[i][j][b];`   `// If i has reached the end of the` `// array return 0` `if` `(i === B) ``return` `0;`   `// If we have exhausted the number of` `// transaction return 0` `if` `(j === 0) ``return` `0;`   `let res;` `if` `(b === 1)` `res = Math.max(` `-pre_sum[i] + solve(j, i + 1, 0, arr),` `solve(j, i + 1, 1, arr)` `);` `else` `res = Math.max(` `pre_sum[i] + solve(j - 1, i + 1, 1, arr),` `solve(j, i + 1, 0, arr)` `);`   `// Return the result` `return` `(dp[i][j][b] = res);` `}`   `function` `maxSum(K, N, arr) {` `pre_sum = ``new` `Array(N + 1).fill(0);`   `// Finding prefix sum of array arr[]` `for` `(let i = 1; i <= N; i++)` `pre_sum[i] = pre_sum[i - 1] + arr[i - 1];`   `// Initializing DP with -1` `for` `(let i = 0; i < dp.length; i++)` `for` `(let j = 0; j < dp[i].length; j++)` `dp[i][j].fill(-1);`   `// Copying n to global B` `B = N + 1;`   `// Function to find maximum` `return` `solve(K, 0, 1, arr);` `}`   `// Driver code` `let arr1 = [4, 1, -3, 7, -5, 6, -2, 1];` `let K1 = 3;` `let N1 = arr1.length;`   `// Function call` `console.log(maxSum(K1, N1, arr1));`   `let arr2 = [8, -1, 4, 2, 6, -6, 4, -1];` `let K2 = 2;` `let N2 = arr2.length;`   `// Function call` `console.log(maxSum(K2, N2, arr2));`

Output

```18
23```

Time Complexity: O(N*K)
Auxiliary Space: O(N*K)

Efficient approach : Using DP Tabulation method ( Iterative approach )

The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.

Implementation :

## C++

 `#include ` `using` `namespace` `std;`   `int` `maxSum(``int` `K, ``int` `N, ``int` `arr[])` `{` `    ``vector<``int``> pre_sum(N + 1, 0);`   `    ``// Finding prefix sum of array arr[]` `    ``for` `(``int` `i = 1; i <= N; i++)` `        ``pre_sum[i] = pre_sum[i - 1] + arr[i - 1];`   `    ``// Initializing DP table with 0` `    ``int` `dp[N + 1][K + 1];` `    ``memset``(dp, 0, ``sizeof``(dp));`   `    ``// dp table to find maximum sum of k non-overlapping subarrays` `    ``for` `(``int` `i = 1; i <= N; i++) {` `        ``for` `(``int` `j = 1; j <= K; j++) {` `            ``int` `curr_max = INT_MIN;` `            ``for` `(``int` `k = i - 1; k >= j - 1; k--) {` `                ``curr_max = max(curr_max, pre_sum[i] - pre_sum[k]);` `                ``dp[i][j] = max(dp[i][j], dp[k][j - 1] + curr_max);` `            ``}` `        ``}` `    ``}`   `    ``// Return the maximum sum` `    ``return` `dp[N][K]+1;` `}`   `// Driver code` `int` `main()` `{` `    ``// Test case 1` `    ``int` `arr1[] = { 4, 1, -3, 7, -5, 6, -2, 1 };` `    ``int` `K1 = 3;` `    ``int` `N1 = ``sizeof``(arr1) / ``sizeof``(arr1[0]);`   `    ``// Function call` `    ``cout << maxSum(K1, N1, arr1) << endl;`   `    ``// Test case 2` `    ``int` `arr2[] = { 8, -1, 4, 2, 6, -6, 4, -1 };` `    ``int` `K2 = 2;` `    ``int` `N2 = ``sizeof``(arr2) / ``sizeof``(arr2[0]);`   `    ``// Function call` `    ``cout << maxSum(K2, N2, arr2);` `    ``return` `0;` `}`

Output

```18
23```

Time Complexity: O(N*K)
Auxiliary Space: O(N*K)

My Personal Notes arrow_drop_up