Skip to content
Related Articles

Related Articles

Improve Article
Maximise array sum after taking non-overlapping sub-arrays of length K
  • Difficulty Level : Hard
  • 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:
 

 

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++




// C++ implementation of the approach
#include <bits/stdc++.h>
#define maxLen 10
using namespace std;
 
// To store the states of dp
int dp[maxLen];
 
// To check if a given state
// has been solved
bool v[maxLen];
 
// To store the prefix-sum
int prefix_sum[maxLen];
 
// Function to fill the prefix_sum[] with
// the prefix sum of the given array
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];
}
 
// Function to find the maximum sum subsequence
// such that no two elements are adjacent
int maxSum(int arr[], int i, int n, int k)
{
    // Base case
    if (i + k > n)
        return 0;
 
    // To check if a state has
    // been solved
    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];
 
    // Required recurrence relation
    dp[i] = max(maxSum(arr, i + 1, n, k),
                x + maxSum(arr, i + k + 1, n, k));
 
    // Returning the value
    return dp[i];
}
 
// Driver code
int main()
{
    int arr[] = { 1, 3, 7, 6 };
    int n = sizeof(arr) / sizeof(int);
    int k = 1;
 
    // Finding prefix-sum
    findPrefixSum(arr, n);
 
    // Finding the maximum possible sum
    cout << maxSum(arr, 0, n, k);
 
    return 0;
}

Java




// Java implementation of the approach
import java.util.*;
 
class GFG
{
 
    static int maxLen = 10;
 
    // To store the states of dp
    static int[] dp = new int[maxLen];
 
    // To check if a given state
    // has been solved
    static boolean[] v = new boolean[maxLen];
 
    // To store the prefix-sum
    static int[] prefix_sum = new int[maxLen];
 
    // Function to fill the prefix_sum[] with
    // the prefix sum of the given array
    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];
        }
    }
 
    // Function to find the maximum sum subsequence
    // such that no two elements are adjacent
    static int maxSum(int arr[], int i, int n, int k)
    {
        // Base case
        if (i + k > n)
        {
            return 0;
        }
 
        // To check if a state has
        // been solved
        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];
        }
 
        // Required recurrence relation
        dp[i] = Math.max(maxSum(arr, i + 1, n, k),
                x + maxSum(arr, i + k + 1, n, k));
 
        // Returning the value
        return dp[i];
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int arr[] = {1, 3, 7, 6};
        int n = arr.length;
        int k = 1;
 
        // Finding prefix-sum
        findPrefixSum(arr, n);
 
        // Finding the maximum possible sum
        System.out.println(maxSum(arr, 0, n, k));
    }
}
 
// This code contributed by Rajput-Ji

Python3




# Python3 implementation of the approach
 
maxLen = 10
 
# To store the states of dp
dp = [0]*maxLen;
 
# To check if a given state
# has been solved
v = [0]*maxLen;
 
# To store the prefix-sum
prefix_sum = [0]*maxLen;
 
# Function to fill the prefix_sum[] with
# the prefix sum of the given array
def findPrefixSum(arr, n) :
 
    prefix_sum[0] = arr[0];
    for i in range(n) :
        prefix_sum[i] = arr[i] + prefix_sum[i - 1];
 
 
# Function to find the maximum sum subsequence
# such that no two elements are adjacent
def maxSum(arr, i, n, k) :
 
    # Base case
    if (i + k > n) :
        return 0;
 
    # To check if a state has
    # been solved
    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];
 
    # Required recurrence relation
    dp[i] = max(maxSum(arr, i + 1, n, k),
                x + maxSum(arr, i + k + 1, n, k));
 
    # Returning the value
    return dp[i];
 
 
# Driver code
if __name__ == "__main__" :
 
    arr = [ 1, 3, 7, 6 ];
     
    n = len(arr);
    k = 1;
 
    # Finding prefix-sum
    findPrefixSum(arr, n);
 
    # Finding the maximum possible sum
    print(maxSum(arr, 0, n, k));
     
# This code is contributed by AnkitRai01

C#




// C# implementation of the approach
using System;
 
class GFG
{
 
    static int maxLen = 10;
 
    // To store the states of dp
    static int[] dp = new int[maxLen];
 
    // To check if a given state
    // has been solved
    static bool[] v = new bool[maxLen];
 
    // To store the prefix-sum
    static int[] prefix_sum = new int[maxLen];
 
    // Function to fill the prefix_sum[] with
    // the prefix sum of the given array
    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];
        }
    }
 
    // Function to find the maximum sum subsequence
    // such that no two elements are adjacent
    static int maxSum(int []arr, int i, int n, int k)
    {
        // Base case
        if (i + k > n)
        {
            return 0;
        }
 
        // To check if a state has
        // been solved
        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];
        }
 
        // Required recurrence relation
        dp[i] = Math.Max(maxSum(arr, i + 1, n, k),
                x + maxSum(arr, i + k + 1, n, k));
 
        // Returning the value
        return dp[i];
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int []arr = {1, 3, 7, 6};
        int n = arr.Length;
        int k = 1;
 
        // Finding prefix-sum
        findPrefixSum(arr, n);
 
        // Finding the maximum possible sum
        Console.Write(maxSum(arr, 0, n, k));
    }
}
 
// This code is contributed by Princi Singh

Javascript




<script>
 
// Javascript implementation of the approach
var maxLen = 10
 
// To store the states of dp
var dp = Array(maxLen);
 
// To check if a given state
// has been solved
var v = Array(maxLen);
 
// To store the prefix-sum
var prefix_sum = Array(maxLen);;
 
// Function to fill the prefix_sum[] with
// the prefix sum of the given array
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 to find the maximum sum subsequence
// such that no two elements are adjacent
function maxSum(arr, i, n, k)
{
    // Base case
    if (i + k > n)
        return 0;
 
    // To check if a state has
    // been solved
    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];
 
    // Required recurrence relation
    dp[i] = Math.max(maxSum(arr, i + 1, n, k),
                x + maxSum(arr, i + k + 1, n, k));
 
    // Returning the value
    return dp[i];
}
 
// Driver code
var arr = [1, 3, 7, 6];
var n = arr.length;
var k = 1;
// Finding prefix-sum
findPrefixSum(arr, n);
// Finding the maximum possible sum
document.write( maxSum(arr, 0, n, k));
 
</script>
Output: 
9

 

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.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer Geeks Classes Live 




My Personal Notes arrow_drop_up
Recommended Articles
Page :