Skip to content
Related Articles

Related Articles

Improve Article
Save Article
Like Article

Maximum sum subsequence with values differing by at least 2

  • Difficulty Level : Hard
  • Last Updated : 27 May, 2021

Given a positive integer array arr[] of size N, the task is to find the maximum sum of a subsequence with the constraint that no 2 numbers in the sequence should be adjacent to the value i.e. if arr[i] is taken into the answer, then neither occurrences of arr[i]-1 nor arr[i]+1 can be selected.

Examples: 

Input: arr[] = {2, 2, 2} 
Output:
Explanation: 
The max sum subsequence will be [2, 2, 2] as it does not contain any occurrence of 1 or 3. Hence sum = 2 + 2 + 2 = 6

Input: arr[] = {2, 2, 3} 
Output: 4
Explanation: 
Subsequence 1: [2, 2] as it does not contain any occurrence of 1 or 3. Hence sum = 2 + 2 = 4 
Subsequence 2: [3] as it does not contain any occurrence of 2 or 4. Hence sum = 3 
Therefore, the max sum = 4

Solution Approach: The idea is to use Dynamic Programming, similar to this article. 

  1. Create a map to store the number of times the element i appears in the sequence.
  2. To find the answer, it would be easy to first break the problem down into smaller problems. In this case, break the sequence into smaller sequences and find an optimal solution for it.
  3. For the sequence of numbers containing only 0, the answer would be 0. Similarly, if a sequence contains only the numbers 0 and 1, then the solution would be to count[1]*1.
  4. Now build a recursive solution to this problem. For a sequence of numbers containing only the numbers, 0 to n, the choice is to either pick the Nth element or not.

dp[i] = max(dp[i – 1], dp[i – 2] + i*freq[i] ) 
dp[i-1] represents not picking the ith number, then the number before it can be considered.
dp[i – 2] + i*freq[i] represents picking the ith number, then the number before it is eliminated. Hence, the number before that is considered. 

C++




// C++ program to find maximum sum
// subsequence with values
// differing by at least 2
 
#include <bits/stdc++.h>
using namespace std;
 
// function to find maximum sum
// subsequence such that two
// adjacent values elements are
// not selected
int get_max_sum(int arr[], int n)
{
    // map to store the frequency
    // of array elements
    unordered_map<int, int> freq;
 
    for (int i = 0; i < n; i++) {
        freq[arr[i]]++;
    }
 
    // make a dp array to store
    // answer upto i th value
    int dp[100001];
    memset(dp, 0, sizeof(dp));
 
    // base cases
    dp[0] = 0;
    dp[1] = freq[0];
 
    // iterate for all possible
    // values  of arr[i]
    for (int i = 2; i <= 100000; i++) {
        dp[i] = max(dp[i - 1],
                    dp[i - 2] + i * freq[i]);
    }
 
    // return the last value
    return dp[100000];
}
 
// Driver function
int main()
{
 
    int N = 3;
    int arr[] = { 2, 2, 3 };
    cout << get_max_sum(arr, N);
    return 0;
}

Java




// Java program to find maximum sum
// subsequence with values
// differing by at least 2
import java.util.*;
import java.lang.*;
 
class GFG{
 
// Function to find maximum sum
// subsequence such that two
// adjacent values elements are
// not selected
public static int get_max_sum(int arr[], int n)
{
     
    // map to store the frequency
    // of array elements
    HashMap<Integer,
            Integer> freq = new HashMap<Integer,
                                        Integer>();
 
    for(int i = 0; i < n; i++)
    {
        if (freq.containsKey(arr[i]))
        {
            int x = freq.get(arr[i]);
            freq.replace(arr[i], x + 1);
        }
        else
            freq.put(arr[i], 1);
    }
 
    // Make a dp array to store
    // answer upto i th value
    int[] dp = new int[100001];
    for(int i = 0; i < 100001; i++)
        dp[i] = 0;
 
    // Base cases
    dp[0] = 0;
    if (freq.containsKey(0))
        dp[1] = freq.get(0);
    else
        dp[1] = 0;
 
    // Iterate for all possible
    // values of arr[i]
    for(int i = 2; i <= 100000; i++)
    {
        int temp = (freq.containsKey(i)) ?
                    freq.get(i) : 0;
        dp[i] = Math.max(dp[i - 1],
                         dp[i - 2] + i * temp);
    }
 
    // Return the last value
    return dp[100000];
}
 
// Driver code
public static void main(String[] args)
{
    int N = 3;
    int arr[] = { 2, 2, 3 };
     
    System.out.println(get_max_sum(arr, N));
}
}
 
// This code is contributed by grand_master

Python3




# Python3 program to find maximum sum
# subsequence with values
# differing by at least 2
from collections import defaultdict
 
# Function to find maximum sum
# subsequence such that two
# adjacent values elements are
# not selected
def get_max_sum(arr, n):
     
    # Map to store the frequency
    # of array elements
    freq = defaultdict(lambda : 0)
     
    for i in range(n):
        freq[arr[i]] += 1
     
    # Make a dp array to store
    # answer upto i th value
    dp = [0] * 100001
     
    # Base cases
    dp[0] = 0
    dp[1] = freq[0]
     
    # Iterate for all possible
    # values of arr[i]
    for i in range(2, 100000 + 1):
        dp[i] = max(dp[i - 1],
                    dp[i - 2] + i * freq[i])
         
    # Return the last value
    return dp[100000]
 
# Driver code
N = 3
arr = [ 2, 2, 3 ]
     
print(get_max_sum(arr, N))
 
# This code is contributed by stutipathak31jan

C#




// C# program to find maximum sum
// subsequence with values
// differing by at least 2
using System;
using System.Collections.Generic;
 
class GFG{
 
// Function to find maximum sum
// subsequence such that two
// adjacent values elements are
// not selected
public static int get_max_sum(int []arr, int n)
{
     
    // map to store the frequency
    // of array elements
    Dictionary<int,
               int> freq = new Dictionary<int,
                                          int>();
 
    for(int i = 0; i < n; i++)
    {
        if (freq.ContainsKey(arr[i]))
        {
            int x = freq[arr[i]];
            freq[arr[i]]= x + 1;
        }
        else
            freq.Add(arr[i], 1);
    }
 
    // Make a dp array to store
    // answer upto i th value
    int[] dp = new int[100001];
    for(int i = 0; i < 100001; i++)
        dp[i] = 0;
 
    // Base cases
    dp[0] = 0;
    if (freq.ContainsKey(0))
        dp[1] = freq[0];
    else
        dp[1] = 0;
 
    // Iterate for all possible
    // values of arr[i]
    for(int i = 2; i <= 100000; i++)
    {
        int temp = (freq.ContainsKey(i)) ?
                    freq[i] : 0;
        dp[i] = Math.Max(dp[i - 1],
                         dp[i - 2] + i * temp);
    }
 
    // Return the last value
    return dp[100000];
}
 
// Driver code
public static void Main(String[] args)
{
    int N = 3;
    int []arr = { 2, 2, 3 };
     
    Console.WriteLine(get_max_sum(arr, N));
}
}
 
// This code is contributed by Amit Katiyar

Javascript




<script>
 
 
// Javascript program to find maximum sum
// subsequence with values
// differing by at least 2
 
// function to find maximum sum
// subsequence such that two
// adjacent values elements are
// not selected
function get_max_sum(arr, n)
{
    // map to store the frequency
    // of array elements
    var freq = new Map();
 
    for (var i = 0; i < n; i++) {
        if(freq.has(arr[i]))
            freq.set(arr[i], freq.get(arr[i])+1)
        else
            freq.set(arr[i], 1)
    }
 
    // make a dp array to store
    // answer upto i th value
    var dp = Array(100001).fill(0);
 
    // base cases
    dp[0] = 0;
    dp[1] = (freq.has(0)?freq.get(0):0);
 
    // iterate for all possible
    // values  of arr[i]
    for (var i = 2; i <= 100000; i++) {
        dp[i] = Math.max(dp[i - 1],
                    dp[i - 2] + i * (freq.has(i)?freq.get(i):0));
    }
 
    // return the last value
    return dp[100000];
}
 
// Driver function
var N = 3;
var arr = [2, 2, 3];
document.write( get_max_sum(arr, N));
 
</script>
Output: 
4

 

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


My Personal Notes arrow_drop_up
Recommended Articles
Page :

Start Your Coding Journey Now!