Maximum sum subsequence made up of at most K distant elements including the first and last array elements
Given an array arr[] consisting of N integers and an integer K, the task is to print the maximum sum possible in a subsequence satisfying the following conditions:
- The elements arr[N – 1] and arr[0] are included in the subsequence.
- Adjacent elements in the subsequence can be at a distance of at most K indices.
Examples:
Input: arr[] = {10, -5, -2, 4, 0, 3}, K = 3
Output: 17
Explanation:
One of possible way is as follows:
Include arr[0] into the subsequence. Sum = 10.
Include arr[3] in the subsequence. Therefore, sum = 10 + 4 = 14.
Include arr[5] in the subsequence. Therefore, total sum = 14 + 3 = 17.
Therefore, the maximum sum possible is 17.
Input: arr[] = {1, -5, -20, 4, -1, 3, -6, -3}, K = 2
Output: 0
Naive Approach: The simplest approach is to find all subsequences possible from arr[] with at most K difference between indices of adjacent elements, starting from index 0 and ending at index (N – 1). Calculate sum of all such subsequences. Finally, print the maximum of all the sums obtained.
Time Complexity: O(N*2N)
Auxiliary Space: O(N)
Efficient Approach: The above approach can be optimized by using a Greedy Algorithm and deque. Follow the steps below to solve the problem:
- Initialize an array, say dp[], to store the maximum value obtained till the current index.
- Initialize a deque of pairs, say Q, to store the pair {dp[i], i}.
- Assign the value of arr[0] to dp[0] and push the pair {dp[0], 0} into the deque.
- Traverse the given array arr[] using the variable i and perform the following steps:
- After completing the above steps, print the value stored at the last index of dp[], i.e. dp[N – 1] as the result.
Below is the implementation of the above approach:
C++
#include<bits/stdc++.h>
using namespace std;
int maxResult( int arr[], int k, int n){
int dp[n] = {0};
dp[0] = arr[0];
deque<pair< int , int >> q;
q.push_back({arr[0], 0});
for ( int i = 1; i < n; i++)
{
dp[i] = arr[i] + q.front().first;
while (q.size() > 0 and q.back().first < dp[i])
q.pop_back();
q.push_back({dp[i], i});
if (i - k == q.front().second)
q.pop_front();
}
return dp[n - 1];
}
int main()
{
int arr[] = {10, -5, -2, 4, 0, 3};
int K = 3;
int n = sizeof (arr)/ sizeof (arr[0]);
cout<<maxResult(arr, K,n);
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
public class GFG {
static class Pair {
int x, y;
Pair( int x, int y) {
this .x = x;
this .y = y;
}
}
private static int maxResult( int [] arr, int k, int n) {
int dp[] = new int [n];
dp[ 0 ] = arr[ 0 ];
Deque<Pair> q = new LinkedList<Pair>();
q.add( new Pair(arr[ 0 ], 0 ));
for ( int i = 1 ; i < n; i++)
{
dp[i] = arr[i] + q.peekFirst().x;
while (q.size() > 0 && q.peekLast().x < dp[i])
q.pollLast();
q.add( new Pair(dp[i], i));
if (i - k == q.peekFirst().y)
q.pollFirst();
}
return dp[n - 1 ];
}
public static void main(String[] args)
{
int arr[] = { 10 , - 5 , - 2 , 4 , 0 , 3 };
int K = 3 ;
int n = arr.length;
System.out.println(maxResult(arr, K,n));
}
}
|
Python3
from collections import deque
def maxResult(arr, k):
dp = [ 0 ] * len (arr)
dp[ 0 ] = arr[ 0 ]
q = deque([(arr[ 0 ], 0 )])
for i in range ( 1 , len (arr)):
dp[i] = arr[i] + q[ 0 ][ 0 ]
while q and q[ - 1 ][ 0 ] < dp[i]:
q.pop()
q.append((dp[i], i))
if i - k = = q[ 0 ][ 1 ]:
q.popleft()
return dp[ - 1 ]
arr = [ 10 , - 5 , - 2 , 4 , 0 , 3 ]
K = 3
print (maxResult(arr, K))
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
class GFG
{
class Pair {
public int x, y;
public Pair( int x, int y) {
this .x = x;
this .y = y;
}
}
static int maxResult( int [] arr, int k, int n) {
int [] dp = new int [n];
dp[0] = arr[0];
List<Pair> q = new List<Pair>();
int l = 0, r= -1;
q.Add( new Pair(arr[0], 0));
r++;
for ( int i = 1 ; i < n ; i++)
{
dp[i] = arr[i] + q[l].x;
while (l<=r && q[r].x < dp[i])
r--;
if (r == q.Count - 1){
q.Add( new Pair(dp[i], i));
} else {
q[r+1] = new Pair(dp[i], i);
}
r++;
if (i - k == q[l].y)
l++;
}
return dp[n - 1];
}
public static void Main( string [] args){
int [] arr = new int []{10, -5, -2, 4, 0, 3};
int K = 3;
int n = arr.Length;
Console.Write(maxResult(arr, K,n));
}
}
|
Javascript
class Pair {
constructor(x, y) {
this .x = x;
this .y = y;
}
}
function maxResult(arr, k, n) {
let dp = new Array(n);
dp[0] = arr[0];
let q = new Array();
let l = 0, r = -1;
q.push( new Pair(arr[0], 0));
r++;
for (let i = 1; i < n; i++) {
dp[i] = arr[i] + q[l].x;
while (l <= r && q[r].x < dp[i])
r--;
if (r == q.length - 1) {
q.push( new Pair(dp[i], i));
} else {
q[r + 1] = new Pair(dp[i], i);
}
r++;
if (i - k == q[l].y)
l++;
}
return dp[n - 1];
}
let arr = [10, -5, -2, 4, 0, 3];
let K = 3;
let n = arr.length;
console.log(maxResult(arr, K, n));
|
Time Complexity: O(N)
Auxiliary Space: O(N)
Last Updated :
21 Nov, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...