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 by 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 = 6Input: arr[] = {2, 2, 3}
Output: 6
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 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 number 0 and 1, then the solution would be count[1]*1.
- Now build a recursive solution for 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] represent not picking the ith number, then the number before it can be considered.
dp[i – 2] + i*freq[i] represent picking the ith number, then the number before it is eliminated, hence the number before that is considered
C++
// C++ progrm 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 arrray 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 progrm 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 arrray 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 arrray 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# progrm 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 arrray 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 |
4
Time Complexity: O(N)
Auxiliary Space: O(N)
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.