Open In App

Find maximum Subsequence Sum according to given conditions

Last Updated : 29 Aug, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an integer array nums and an integer K, The task is to find the maximum sum of a non-empty subsequence of the array such that for every two consecutive integers in the subsequence, nums[i] and nums[j], where i < j, the condition j – i <= K is satisfied. 

A subsequence of an array is obtained by deleting some number of elements (can be zero) from the array, leaving the remaining elements in their original order. 

Examples: 

Input: nums = [10, 2, -10, 5, 20], K = 2
Output: 37
Explanation: The subsequence is [10, 2, 5, 20].

Input: nums = [-1, -2, -3], K = 1
Output: -1

Input: nums = [10, -2, -10, -5, 20], K = 2
Output: 23

Approach: 

  • The optimal solution of this problem can be achieved by using the Sliding Window Maximum and Dynamic Programming .
  • At any index i after calculating the maximum sum for i, nums[i] will now store the maximum possible sum that can be obtained from a subsequence ending at i.
  • To calculate the maximum possible sum for every index i , check what is the maximum value that can be obtained from a window of size K before it. If the maximum value is negative, use zero instead.
  • To use the values of calculated sums optimally we use a deque to store the sums along with their indexes in an increasing order of the sums . We also pop the element from the back when its index goes out of the window k of current index i.
     

CPP




// C++ program to find the maximum sum
// subsequence under given constraint
#include <bits/stdc++.h>
using namespace std;
 
// Function return the maximum sum
int ConstrainedSubsetSum(vector<int>& nums,
                         int k)
{
    deque<pair<int, int> > d;
     
    // Iterating the given array
    for (int i = 0; i < nums.size(); i++)
    {
       
        // Check if deque is empty
        nums[i] += d.size()
            ? max(d.back().first, 0) : 0;
         
        while (d.size() &&
               d.front().first < nums[i])
            d.pop_front();
         
        d.push_front({ nums[i], i });
         
        if (d.back().second == i - k)
            d.pop_back();
    }
 
    int ans = nums[0];
     
    for (auto x : nums)
        ans = max(ans, x);
 
    return ans;
}
 
// Driver code
int main()
{
    vector<int> nums = { 10, -2, -10,
                        -5, 20 };
    int K = 2;
     
    // Function call
    cout << ConstrainedSubsetSum(nums, K)
        << endl;
    return 0;
}


Java




// Java program to find the maximum sum
// subsequence under given constraint
 
import java.io.*;
import java.util.*;
 
class GFG {
 
    // pair class
    static class pair {
        int first, second;
        public pair(int first, int second)
        {
            this.first = first;
            this.second = second;
        }
    }
 
    // Function to return the maximum sum
    static int ConstrainedSubsetSum(int[] nums, int k)
    {
        Deque<pair> d = new LinkedList<>();
 
        // Iterating the given array
        for (int i = 0; i < nums.length; i++) {
 
            // Check if deque is empty
            nums[i]
                += (d.size() != 0
                        ? Math.max(d.peekLast().first, 0)
                        : 0);
            while (d.size() != 0
                   && d.peekFirst().first < nums[i]) {
                d.removeFirst();
            }
            d.offerFirst(new pair(nums[i], i));
            if (d.peekLast().second == i - k) {
                d.removeLast();
            }
        }
        int ans = nums[0];
        for (int i = 0; i < nums.length; i++) {
            ans = Math.max(ans, nums[i]);
        }
        return ans;
    }
 
      // Driver code
    public static void main(String[] args)
    {
        int[] nums = { 10, -2, -10, -5, 20 };
        int K = 2;
 
        // Function call
        System.out.print(ConstrainedSubsetSum(nums, K));
    }
}
 
// This code is contributed by lokeshmvs21.


Python3




# Python code
from collections import deque
 
def ConstrainedSubsetSum(nums, k):
    d = deque()
    # Iterating the given array
    for i in range(len(nums)):
        nums[i] += d[-1][0] if d and d[-1][0] > 0 else 0
        while d and d[0][0] < nums[i]:
            d.popleft()
        d.appendleft((nums[i], i))
        if d and d[-1][1] == i - k:
            d.pop()
    ans=nums[0]
    for i in range(1,len(nums)):
      ans=max(ans,nums[i])
    return ans
 
# Driver code
nums = [10, -2, -10, -5, 20]
K = 2
print(ConstrainedSubsetSum(nums, K))
 
# This code is contributed by Utkarsh


C#




using System;
using System.Collections.Generic;
 
class GFG {
    // pair class
    class Pair {
        public int First { get; set; }
        public int Second { get; set; }
        public Pair(int first, int second) {
            First = first;
            Second = second;
        }
    }
 
    // Function to return the maximum sum
    static int ConstrainedSubsetSum(int[] nums, int k) {
        LinkedList<Pair> d = new LinkedList<Pair>();
 
        // Iterating the given array
        for (int i = 0; i < nums.Length; i++) {
 
            // Check if deque is empty
            nums[i] += (d.Count != 0 ? Math.Max(d.Last.Value.First, 0) : 0);
            while (d.Count != 0 && d.First.Value.First < nums[i]) {
                d.RemoveFirst();
            }
            d.AddFirst(new Pair(nums[i], i));
            if (d.Last.Value.Second == i - k) {
                d.RemoveLast();
            }
        }
        int ans = nums[0];
        foreach (Pair pair in d) {
            ans = Math.Max(ans, pair.First);
        }
        return ans;
    }
 
    // Driver code
    public static void Main(string[] args) {
        int[] nums = { 10, -2, -10, -5, 20 };
        int k = 2;
 
        // Function call
        Console.Write(ConstrainedSubsetSum(nums, k));
    }
}


Javascript




// JS program to find the maximum sum
// subsequence under given constralet
 
// Function return the maximum sum
function ConstrainedSubsetSum(nums, k)
{
    let d = [];
     
    // Iterating the given array
    for (let i = 0; i < nums.length; i++)
    {
       
        // Check if deque is empty
        nums[i] += d.length
            ? Math.max(d[d.length - 1][0], 0) : 0;
 
         
        while (d.length &&
               d[0][0] < nums[i])
            d.shift();
 
         
        d.unshift([nums[i], i]);
         
        if (d[d.length - 1][1] === i - k)
            d.pop();
    }
 
    let ans = nums[0];
     
    for (let x of nums)
        ans = Math.max(ans, x);
 
    return ans;
}
 
// Driver code
let nums = [ 10, -2, -10, -5, 20 ];
let K = 2;
 
// Function call
console.log(ConstrainedSubsetSum(nums, K));


Output

23



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



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads