Maximise array sum after taking non-overlapping sub-arrays of length K
Last Updated :
19 May, 2021
Given an integer array arr[] of length N and an integer K, the task is to select some non-overlapping sub-arrays such that each sub-array is exactly of length K, no two sub-arrays are adjacent and sum of all the elements of the selected sub-arrays is maximum.
Examples:
Input: arr[] = {1, 2, 3, 4, 5}, K = 2
Output: 12
Sub-arrays that maximizes sum will be {{1, 2}, {4, 5}}.
Thus, the answer will be 12.
Input: arr[] = {1, 1, 1, 1, 1}, K = 1
Output: 3
Approach: This problem can be solved using dynamic programming. Let’s suppose we are at an index i. Let dp[i] be defined as the maximum sum of elements of all possible subsets of sub-array arr[i…n-1] satisfying above conditions.
We will have two possible choices i.e. select the sub-array arr[i…i+k-1] and solve for dp[i + k + 1] or reject it and solve for dp[i + 1].
Thus, recurrence relation will be
dp[i] = max(dp[i + 1], arr[i] + arr[i + 1] + arr[i + 2] + … + arr[i + k – 1] + dp[i + k + 1])
Since, the values of K can be large, we will use prefix-sum array to find the sum of all the elements of the sub-array arr[i…i + k – 1] in O(1).
Overall, time complexity of the algorithm will be O(N).
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
#define maxLen 10
using namespace std;
int dp[maxLen];
bool v[maxLen];
int prefix_sum[maxLen];
void findPrefixSum( int arr[], int n)
{
prefix_sum[0] = arr[0];
for ( int i = 1; i < n; i++)
prefix_sum[i] = arr[i] + prefix_sum[i - 1];
}
int maxSum( int arr[], int i, int n, int k)
{
if (i + k > n)
return 0;
if (v[i])
return dp[i];
v[i] = 1;
int x;
if (i == 0)
x = prefix_sum[k - 1];
else
x = prefix_sum[i + k - 1] - prefix_sum[i - 1];
dp[i] = max(maxSum(arr, i + 1, n, k),
x + maxSum(arr, i + k + 1, n, k));
return dp[i];
}
int main()
{
int arr[] = { 1, 3, 7, 6 };
int n = sizeof (arr) / sizeof ( int );
int k = 1;
findPrefixSum(arr, n);
cout << maxSum(arr, 0, n, k);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int maxLen = 10 ;
static int [] dp = new int [maxLen];
static boolean [] v = new boolean [maxLen];
static int [] prefix_sum = new int [maxLen];
static void findPrefixSum( int arr[], int n)
{
prefix_sum[ 0 ] = arr[ 0 ];
for ( int i = 1 ; i < n; i++)
{
prefix_sum[i] = arr[i] + prefix_sum[i - 1 ];
}
}
static int maxSum( int arr[], int i, int n, int k)
{
if (i + k > n)
{
return 0 ;
}
if (v[i])
{
return dp[i];
}
v[i] = true ;
int x;
if (i == 0 )
{
x = prefix_sum[k - 1 ];
}
else
{
x = prefix_sum[i + k - 1 ] - prefix_sum[i - 1 ];
}
dp[i] = Math.max(maxSum(arr, i + 1 , n, k),
x + maxSum(arr, i + k + 1 , n, k));
return dp[i];
}
public static void main(String[] args)
{
int arr[] = { 1 , 3 , 7 , 6 };
int n = arr.length;
int k = 1 ;
findPrefixSum(arr, n);
System.out.println(maxSum(arr, 0 , n, k));
}
}
|
Python3
maxLen = 10
dp = [ 0 ] * maxLen;
v = [ 0 ] * maxLen;
prefix_sum = [ 0 ] * maxLen;
def findPrefixSum(arr, n) :
prefix_sum[ 0 ] = arr[ 0 ];
for i in range (n) :
prefix_sum[i] = arr[i] + prefix_sum[i - 1 ];
def maxSum(arr, i, n, k) :
if (i + k > n) :
return 0 ;
if (v[i]) :
return dp[i];
v[i] = 1 ;
if (i = = 0 ) :
x = prefix_sum[k - 1 ];
else :
x = prefix_sum[i + k - 1 ] - prefix_sum[i - 1 ];
dp[i] = max (maxSum(arr, i + 1 , n, k),
x + maxSum(arr, i + k + 1 , n, k));
return dp[i];
if __name__ = = "__main__" :
arr = [ 1 , 3 , 7 , 6 ];
n = len (arr);
k = 1 ;
findPrefixSum(arr, n);
print (maxSum(arr, 0 , n, k));
|
C#
using System;
class GFG
{
static int maxLen = 10;
static int [] dp = new int [maxLen];
static bool [] v = new bool [maxLen];
static int [] prefix_sum = new int [maxLen];
static void findPrefixSum( int []arr, int n)
{
prefix_sum[0] = arr[0];
for ( int i = 1; i < n; i++)
{
prefix_sum[i] = arr[i] + prefix_sum[i - 1];
}
}
static int maxSum( int []arr, int i, int n, int k)
{
if (i + k > n)
{
return 0;
}
if (v[i])
{
return dp[i];
}
v[i] = true ;
int x;
if (i == 0)
{
x = prefix_sum[k - 1];
}
else
{
x = prefix_sum[i + k - 1] - prefix_sum[i - 1];
}
dp[i] = Math.Max(maxSum(arr, i + 1, n, k),
x + maxSum(arr, i + k + 1, n, k));
return dp[i];
}
public static void Main(String[] args)
{
int []arr = {1, 3, 7, 6};
int n = arr.Length;
int k = 1;
findPrefixSum(arr, n);
Console.Write(maxSum(arr, 0, n, k));
}
}
|
Javascript
<script>
var maxLen = 10
var dp = Array(maxLen);
var v = Array(maxLen);
var prefix_sum = Array(maxLen);;
function findPrefixSum(arr, n)
{
prefix_sum[0] = arr[0];
for ( var i = 1; i < n; i++)
prefix_sum[i] = arr[i] + prefix_sum[i - 1];
}
function maxSum(arr, i, n, k)
{
if (i + k > n)
return 0;
if (v[i])
return dp[i];
v[i] = 1;
var x;
if (i == 0)
x = prefix_sum[k - 1];
else
x = prefix_sum[i + k - 1] - prefix_sum[i - 1];
dp[i] = Math.max(maxSum(arr, i + 1, n, k),
x + maxSum(arr, i + k + 1, n, k));
return dp[i];
}
var arr = [1, 3, 7, 6];
var n = arr.length;
var k = 1;
findPrefixSum(arr, n);
document.write( maxSum(arr, 0, n, k));
</script>
|
Share your thoughts in the comments
Please Login to comment...