Given an array arr[] of positive numbers, find the maximum sum of a subsequence with the constraint that no 2 numbers in the sequence should be adjacent in the array where the last and the first elements are assumed adjacent.
Examples:
Input: arr[] = {3, 5, 3}
Output: 5
Explanation:
We cannot take the first and last elements because they are considered to be adjacent, hence the output is 5.
Input arr[] = {1, 223, 41, 4, 414, 5, 16}
Output: 653
Explanation:
Taking elements form the index 1, 4 and 6 we get the maximum sum as 653.
Approach: The idea is to use the Memorization algorithm to solve the problem mentioned above. The most important observation is that the first and the last elements can never be chosen together. So, we can break the problem into two parts:
- The maximum sum we can get from index 0 to the size of the array – 2
- The maximum sum we can get from index 1 to size of the array – 1
The answer will be the maximum of these two sums which can be solved by using Dynamic Programming.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > dp;
int maxSum( int i, vector< int >& subarr)
{
if (i >= subarr.size())
return 0;
if (dp[i] != -1)
return dp[i];
return dp[i]
= max(maxSum(i + 1, subarr),
subarr[i]
+ maxSum(i + 2, subarr));
}
int Func(vector< int > arr)
{
vector< int > subarr = arr;
subarr.pop_back();
dp.resize(subarr.size(), -1);
int max1 = maxSum(0, subarr);
subarr = arr;
subarr.erase(subarr.begin());
dp.clear();
dp.resize(subarr.size(), -1);
int max2 = maxSum(0, subarr);
cout << max(max1, max2) << endl;
}
int main()
{
vector< int > arr = { 1, 2, 3, 1 };
Func(arr);
return 0;
}
|
Java
import java.util.*;
class GFG{
static Vector<Integer> dp =
new Vector<>();
static int maxSum( int i,
Vector<Integer> subarr)
{
if (i >= subarr.size())
return 0 ;
if (dp.get(i) != - 1 )
return dp.get(i);
dp.add(i, Math.max(maxSum(i + 1 , subarr),
subarr.get(i) +
maxSum(i + 2 , subarr)));
return dp.get(i);
}
static void Func(Vector<Integer> arr)
{
Vector<Integer> subarr =
new Vector<>();
subarr.addAll(arr);
subarr.remove(subarr.size() - 1 );
dp.setSize(subarr.size());
Collections.fill(dp, - 1 );
int max1 = maxSum( 0 , subarr);
subarr = arr;
subarr.remove( 0 );
dp.clear();
dp.setSize(subarr.size());
Collections.fill(dp, - 1 );
int max2 = maxSum( 0 , subarr);
System.out.print(Math.max(max1, max2) + "\n" );
}
public static void main(String[] args)
{
Vector<Integer> arr = new Vector<>();
arr.add( 1 );
arr.add( 2 );
arr.add( 3 );
arr.add( 1 );
Func(arr);
}
|
Python3
dp = []
def maxSum(i, subarr):
if (i > = len (subarr)):
return 0
if (dp[i] ! = - 1 ):
return dp[i]
dp[i] = max (maxSum(i + 1 , subarr),
subarr[i] +
maxSum(i + 2 , subarr))
return dp[i]
def Func(arr):
subarr = arr
subarr.pop()
global dp
dp = [ - 1 ] * ( len (subarr))
max1 = maxSum( 0 , subarr)
subarr = arr
subarr = subarr[:]
del dp
dp = [ - 1 ] * ( len (subarr))
max2 = maxSum( 0 , subarr)
print ( max (max1, max2))
if __name__ = = "__main__" :
arr = [ 1 , 2 , 3 , 1 ]
Func(arr)
|
C#
using System;
using System.Collections;
using System.Collections.Generic;
class GFG
{
static List< int > dp = new List< int >();
static int maxSum( int i, List< int > subarr)
{
if (i >= subarr.Count)
return 0;
if (dp[i] != -1)
return dp[i];
dp[i] = Math.Max(maxSum(i + 1, subarr), subarr[i] + maxSum(i + 2, subarr));
return dp[i];
}
static void Func(List< int > arr)
{
List< int > subarr = new List< int >(arr);
subarr.RemoveAt(subarr.Count - 1);
for ( int i = 0 ; i < subarr.Count ; i++){
dp.Add(-1);
}
int max1 = maxSum(0, subarr);
subarr = arr;
subarr.RemoveAt(0);
dp.Clear();
for ( int i = 0 ; i < subarr.Count ; i++){
dp.Add(-1);
}
int max2 = maxSum(0, subarr);
Console.WriteLine(Math.Max(max1, max2));
}
public static void Main( string [] args){
List< int > arr = new List< int >();
arr.Add(1);
arr.Add(2);
arr.Add(3);
arr.Add(1);
Func(arr);
}
}
|
Javascript
<script>
let dp =[];
function maxSum(i,subarr)
{
if (i >= subarr.length)
return 0;
if (dp[i] != -1)
return dp[i];
dp[i] = Math.max(maxSum(i + 1, subarr),
subarr[i] +
maxSum(i + 2, subarr));
return dp[i];
}
function Func(arr)
{
let subarr =arr;
subarr.pop();
dp= new Array(subarr.length);
for (let i=0;i<subarr.length;i++)
{
dp[i]=-1;
}
let max1 = maxSum(0, subarr);
subarr = arr;
subarr.shift();
dp=[];
dp= new Array(subarr.length);
for (let i=0;i<dp.length;i++)
{
dp[i]=-1;
}
let max2 = maxSum(0, subarr);
document.write(Math.max(max1, max2) + "<br>" );
}
let arr=[1,2,3,1];
Func(arr);
</script>
|
Time Complexity: O(N)
Auxiliary Space Complexity: O(N)
Method 2: Tabulation
C++
#include <bits/stdc++.h>
using namespace std;
int findMax(vector< int > arr, int n, vector< int > &dp){
dp[0] = arr[0] ;
for ( int i = 1 ; i <= n ; i++ ){
int pick = arr[i];
if (i > 1){
pick += dp[i-2] ;
}
int notPick = 0 + dp[i-1] ;
dp[i] = max(pick, notPick) ;
}
return dp[n] ;
}
int Func(vector< int > nums)
{
if (nums.size() == 1){
return nums[0] ;
}
vector< int > v1, v2 ;
int n = nums.size() ;
vector< int > dp(nums.size() , -1) ;
for ( int i = 0 ; i < n ; i++ ){
if (i != 0) v1.push_back(nums[i] ) ;
if (i != n-1) v2.push_back(nums[i] ) ;
}
cout<< max(findMax(v1, n-2, dp) , findMax(v2, n-2, dp)) ;
}
int main()
{
vector< int > arr = { 1, 2, 3, 1 };
Func(arr);
return 0;
}
|
Java
import java.util.*;
class GFG {
static int findMax(List<Integer> arr, int n, int []dp){
dp[ 0 ] = arr.get( 0 ) ;
for ( int i = 1 ; i <= n ; i++ ){
int pick = arr.get(i);
if (i > 1 ){
pick += dp[i- 2 ] ;
}
int notPick = 0 + dp[i- 1 ] ;
dp[i] = Math.max(pick, notPick) ;
}
return dp[n] ;
}
static int Func( int [] nums)
{
if (nums.length == 1 ){
return nums[ 0 ];
}
List<Integer> v1 = new ArrayList<>();
List<Integer> v2 = new ArrayList<>();
int n = nums.length ;
int dp[] = new int [nums.length];
Arrays.fill(dp,- 1 );
for ( int i = 0 ; i < n ; i++ ){
if (i != 0 ) v1.add(nums[i] ) ;
if (i != n- 1 ) v2.add(nums[i] ) ;
}
System.out.println(Math.max(findMax(v1, n- 2 , dp) , findMax(v2, n- 2 , dp)));
return 0 ;
}
public static void main (String[] args) {
int [] arr = { 1 , 2 , 3 , 1 };
Func(arr);
}
}
|
Python3
def findMax(arr, n, dp):
dp[ 0 ] = arr[ 0 ]
for i in range ( 1 ,n + 1 ):
pick = arr[i]
if (i > 1 ):
pick + = dp[i - 2 ]
notPick = 0 + dp[i - 1 ]
dp[i] = max (pick, notPick)
return dp[n]
def Func(nums):
if ( len (nums) = = 1 ):
return nums[ 0 ]
v1 = []
v2 = []
n = len (nums)
dp = [ - 1 for i in range ( len (nums))]
for i in range (n):
if (i ! = 0 ):
v1.append(nums[i])
if (i ! = n - 1 ):
v2.append(nums[i])
print ( max (findMax(v1, n - 2 , dp) , findMax(v2, n - 2 , dp)))
arr = [ 1 , 2 , 3 , 1 ]
Func(arr)
|
C#
using System;
using System.Collections.Generic;
public class HelloWorld
{
public static int findMax(List< int > arr, int n, List< int > dp){
dp[0] = arr[0] ;
for ( int i = 1 ; i <= n ; i++ ){
int pick = arr[i];
if (i > 1){
pick += dp[i-2] ;
}
int notPick = 0 + dp[i-1] ;
dp[i] = Math.Max(pick, notPick) ;
}
return dp[n] ;
}
public static int Func(List< int > nums)
{
if (nums.Count == 1){
return nums[0] ;
}
List< int > v1 = new List< int >();
List< int > v2 = new List< int >();
int n = nums.Count ;
List< int > dp = new List< int >();
for ( int i =0;i<nums.Count;i++)
{
dp.Add(-1);
}
for ( int i = 0 ; i < n ; i++ ){
if (i != 0) v1.Add(nums[i] ) ;
if (i != n-1) v2.Add(nums[i] ) ;
}
return Math.Max(findMax(v1, n-2, dp),findMax(v2, n-2, dp));
}
public static void Main( string [] args)
{
List< int > arr = new List< int >();
arr.Add(1);
arr.Add(2);
arr.Add(3);
arr.Add(1);
Console.WriteLine(Func(arr));
}
}
|
Javascript
<script>
function findMax(arr, n, dp)
{
dp[0] = arr[0] ;
for (let i = 1 ; i <= n ; i++ )
{
let pick = arr[i];
if (i > 1)
{
pick += dp[i-2] ;
}
let notPick = 0 + dp[i-1] ;
dp[i] = Math.max(pick, notPick) ;
}
return dp[n];
}
function Func(nums)
{
if (nums.length == 1){
return nums[0] ;
}
let v1 = [], v2 = [];
let n = nums.length ;
let dp = new Array(nums.length).fill(-1) ;
for (let i = 0 ; i <br n ; i++ ){
if (i != 0) v1.push(nums[i]) ;
if (i != n-1) v2.push(nums[i]) ;
}
document.write(Math.max(findMax(v1, n-2, dp) , findMax(v2, n-2, dp)), "</br>" );
}
let arr = [ 1, 2, 3, 1 ];
Func(arr);
</script>
|
Time Complexity: O(N)
Auxiliary Space Complexity: O(N)
Similar article: Maximum sum in circular array such that no two elements are adjacent