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