Maximum sum subsequence with values differing by at least 2
Last Updated :
02 Oct, 2023
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: 6
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.
- Create a map to store the number of times the element i appears in the sequence.
- 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.
- 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.
- 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>
Time Complexity: O(N)
Auxiliary Space: O(N)
Another approach : Without using DP array
In previous approach the current value dp[i[ is only depend only on the previous 2 values i.e. dp[i-1] and dp[i-2]. So to optimize the space complexity we can use variables to keep track of previous values.
Implementation Steps:
- Create 2 variables prev1 and prev2 to keep track o previous values of DP.
- Initialize base case prev1 = prev2 = 0.
- Create a variable curr to store current value.
- Iterate over subproblem using loop and update curr.
- After every iteration update prev1 and prev2 for further iterations.
- At last return curr.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
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]]++;
}
// initialize variables
int prev1 = 0, prev2 = 0, curr = 0;
// iterate for all possible
// values of arr[i]
for (int i = 1; i <= 100000; i++) {
curr = max(prev1, prev2 + i * freq[i]);
prev2 = prev1;
prev1 = curr;
}
// return the maximum sum subsequence
return curr;
}
int main()
{
int N = 3;
int arr[] = { 2, 2, 3 };
cout << get_max_sum(arr, N);
return 0;
}
Java
import java.util.HashMap;
import java.util.Map;
public class Main {
static int getMaxSum(int[] arr, int n) {
// Map to store the frequency of array elements
Map<Integer, Integer> freq = new HashMap<>();
for (int i = 0; i < n; i++) {
freq.put(arr[i], freq.getOrDefault(arr[i], 0) + 1);
}
// Initialize variables
int prev1 = 0, prev2 = 0, curr = 0;
// Iterate for all possible values of arr[i]
for (int i = 1; i <= 100000; i++) {
curr = Math.max(prev1, prev2 + i * freq.getOrDefault(i, 0));
prev2 = prev1;
prev1 = curr;
}
// Return the maximum sum subsequence
return curr;
}
public static void main(String[] args) {
int N = 3;
int[] arr = {2, 2, 3};
System.out.println(getMaxSum(arr, N));
}
}
Python3
from collections import defaultdict
def get_max_sum(arr, n):
# dictionary to store the frequency
# of array elements
freq = defaultdict(int)
for i in range(n):
freq[arr[i]] += 1
# initialize variables
prev1 = 0
prev2 = 0
curr = 0
# iterate for all possible
# values of i
for i in range(1, 100001):
curr = max(prev1, prev2 + i * freq[i])
prev2 = prev1
prev1 = curr
# return the maximum sum subsequence
return curr
# Driver code
if __name__ == '__main__':
N = 3
arr = [2, 2, 3]
print(get_max_sum(arr, N))
C#
using System;
using System.Collections.Generic;
class GFG
{
public static int GetMaxSum(int[] arr, int n)
{
// Dictionary 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]))
{
freq[arr[i]] = 1;
}
else
{
freq[arr[i]]++;
}
}
// Initialize variables
int prev1 = 0, prev2 = 0, curr = 0;
// Iterate for all possible
// values of arr[i]
for (int i = 1; i <= 100000; i++)
{
curr = Math.Max(prev1, prev2 + i * (freq.ContainsKey(i) ? freq[i] : 0));
prev2 = prev1;
prev1 = curr;
}
// Return the maximum sum subsequence
return curr;
}
public static void Main()
{
int N = 3;
int[] arr = { 2, 2, 3 };
Console.WriteLine(GetMaxSum(arr, N));
}
}
// This code is contributed by rambabuguphka
JavaScript
// Javascript code addition
function getMaxSum(arr, n) {
// Map to store the frequency of array elements
const freq = new Map();
for (let i = 0; i < n; i++) {
freq.set(arr[i], (freq.get(arr[i]) || 0) + 1);
}
// Initialize variables
let prev1 = 0;
let prev2 = 0;
let curr = 0;
// Iterate for all possible values of arr[i]
for (let i = 1; i <= 100000; i++) {
curr = Math.max(prev1, prev2 + i * (freq.get(i) || 0));
prev2 = prev1;
prev1 = curr;
}
// Return the maximum sum subsequence
return curr;
}
const arr = [2, 2, 3];
const n = 3;
console.log(getMaxSum(arr, n));
// The code is contributed by Nidhi goel.
Output:
4
Time Complexity: O(N) for map
Auxiliary Space: O(N)
Similar Reads
Longest alternating subsequence with maximum sum | Set 2 Given an array arr[] of size N, consisting of positive and negative integers, the task is to find the longest alternating subsequence(i.e. the sign of every element is opposite to that of its previous element) from the given array which has the maximum sum.Examples: Input: arr[] = {-2, 10, 3, -8, -4
7 min read
Maximum sum subsequence with at-least k distant elements Given an array and a number k, find a subsequence such that Sum of elements in subsequence is maximumIndices of elements of subsequence differ atleast by k Examples Input : arr[] = {4, 5, 8, 7, 5, 4, 3, 4, 6, 5} k = 2 Output: 19 Explanation: The highest value is obtained if you pick indices 1, 4, 7,
6 min read
Longest Subsequence with difference between max and min at most K Given an array arr[] of size N and a non-negative integer K, the task is to find the length of the longest subsequence such that the difference between the maximum and the minimum of the subsequence is at most K. Examples: Input: arr[] = {1, 3, 5, 4, 2}, N = 5, K = 3Output: 4Explanation: If we consi
5 min read
Maximum Subsequence sum with difference among consecutive numbers less than K Given an array arr[], find the maximum sum that can be achieved by picking a subsequence such that the difference between consecutive elements in the subsequence is less than or equal to a given number 'K'. Examples: Input: arr[] = {1, 8, 9, 4, 6, 7}, K = 2Output: 24. Explanation: The maximum sum ca
7 min read
Maximum sum alternating subsequence Given an array, the task is to find sum of maximum sum alternating subsequence starting with first element. Here alternating sequence means first decreasing, then increasing, then decreasing, ... For example 10, 5, 14, 3 is an alternating sequence. Note that the reverse type of sequence (increasing
13 min read