Open In App

Maximum sum such that no two elements are adjacent | Set 2

Last Updated : 30 Sep, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array 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. So 3 2 7 10 should return 13 (sum of 3 and 10) or 3 2 5 10 7 should return 15 (sum of 3, 5, and 7).

Examples: 

Input :  arr[] = {3, 5, 3} 
Output : 6
Explanation :
Selecting indexes 0 and 2 will maximise the sum
i.e 3+3 = 6
Input : arr[] = {2, 5, 2}
Output : 5

We have already discussed the efficient approach of solving this problem in the previous article.
However, we can also solve this problem using the Dynamic Programming approach.
Dynamic Programming Approach: Let’s decide the states of ‘dp’. Let dp[i] be the largest possible sum for the sub-array starting from index ‘i’ and ending at index ‘N-1’. Now, we have to find a recurrence relation between this state and a lower-order state.
In this case for an index ‘i’, we will have two choices.  

1) Choose the current index:
In this case, the relation will be dp[i] = arr[i] + dp[i+2]
2) Skip the current index:
Relation will be dp[i] = dp[i+1]

We will choose the path that maximizes our result. 
Thus, the final relation will be:  

dp[i] = max(dp[i+2]+arr[i], dp[i+1])

Below is the implementation of the above approach:  

C++




// C++ program to implement above approach
 
#include <bits/stdc++.h>
#define maxLen 10
using namespace std;
 
// variable to store states of dp
int dp[maxLen];
 
// variable to check if a given state
// has been solved
bool v[maxLen];
 
// Function to find the maximum sum subsequence
// such that no two elements are adjacent
int maxSum(int arr[], int i, int n)
{
    // Base case
    if (i >= n)
        return 0;
 
    // To check if a state has
    // been solved
    if (v[i])
        return dp[i];
    v[i] = 1;
 
    // Required recurrence relation
    dp[i] = max(maxSum(arr, i + 1, n),
                arr[i] + maxSum(arr, i + 2, n));
 
    // Returning the value
    return dp[i];
}
 
// Driver code
int main()
{
    int arr[] = { 12, 9, 7, 33 };
 
    int n = sizeof(arr) / sizeof(int);
 
    cout << maxSum(arr, 0, n);
 
    return 0;
}


Java




// Java program to implement above approach
class GFG
{
 
static int maxLen = 10;
 
// variable to store states of dp
static int dp[] = new int[maxLen];
 
// variable to check if a given state
// has been solved
static boolean v[] = new boolean[maxLen];
 
// Function to find the maximum sum subsequence
// such that no two elements are adjacent
static int maxSum(int arr[], int i, int n)
{
    // Base case
    if (i >= n)
        return 0;
 
    // To check if a state has
    // been solved
    if (v[i])
        return dp[i];
    v[i] = true;
 
    // Required recurrence relation
    dp[i] = Math.max(maxSum(arr, i + 1, n),
                arr[i] + maxSum(arr, i + 2, n));
 
    // Returning the value
    return dp[i];
}
 
// Driver code
public static void main(String args[])
{
    int arr[] = { 12, 9, 7, 33 };
    int n = arr.length;
    System.out.println( maxSum(arr, 0, n));
}
}
 
// This code is contributed by Arnab Kundu


Python3




# Python 3 program to implement above approach
maxLen = 10
 
# variable to store states of dp
dp = [0 for i in range(maxLen)]
 
# variable to check if a given state
# has been solved
v = [0 for i in range(maxLen)]
 
# Function to find the maximum sum subsequence
# such that no two elements are adjacent
def maxSum(arr, i, n):
    # Base case
    if (i >= n):
        return 0
 
    # To check if a state has
    # been solved
    if (v[i]):
        return dp[i]
    v[i] = 1
 
    # Required recurrence relation
    dp[i] = max(maxSum(arr, i + 1, n),
            arr[i] + maxSum(arr, i + 2, n))
 
    # Returning the value
    return dp[i]
 
# Driver code
if __name__ == '__main__':
    arr = [12, 9, 7, 33]
 
    n = len(arr)
    print(maxSum(arr, 0, n))
 
# This code is contributed by
# Surendra_Gangwar


C#




// C# program to implement above approach
using System;
 
class GFG
{
 
static int maxLen = 10;
 
// variable to store states of dp
static int[] dp = new int[maxLen];
 
// variable to check if a given state
// has been solved
static bool[] v = new bool[maxLen];
 
// Function to find the maximum sum subsequence
// such that no two elements are adjacent
static int maxSum(int[] arr, int i, int n)
{
    // Base case
    if (i >= n)
        return 0;
 
    // To check if a state has
    // been solved
    if (v[i])
        return dp[i];
    v[i] = true;
 
    // Required recurrence relation
    dp[i] = Math.Max(maxSum(arr, i + 1, n),
                arr[i] + maxSum(arr, i + 2, n));
 
    // Returning the value
    return dp[i];
}
 
// Driver code
public static void Main()
{
    int[] arr = { 12, 9, 7, 33 };
    int n = arr.Length;
    Console.Write( maxSum(arr, 0, n));
}
}
 
// This code is contributed by ChitraNayal


Javascript




<script>
 
// Javascript program to implement above approach
var maxLen = 10;
 
// variable to store states of dp
var dp = Array(maxLen);
 
// variable to check if a given state
// has been solved
var v = Array(maxLen);
 
// Function to find the maximum sum subsequence
// such that no two elements are adjacent
function maxSum(arr, i, n)
{
    // Base case
    if (i >= n)
        return 0;
 
    // To check if a state has
    // been solved
    if (v[i])
        return dp[i];
    v[i] = 1;
 
    // Required recurrence relation
    dp[i] = Math.max(maxSum(arr, i + 1, n),
                arr[i] + maxSum(arr, i + 2, n));
 
    // Returning the value
    return dp[i];
}
 
// Driver code
var arr = [12, 9, 7, 33 ];
var n = arr.length;
document.write( maxSum(arr, 0, n));
 
</script>


PHP




<?php
// PHP program to implement above approach
 
$maxLen = 10;
 
// variable to store states of dp
$dp = array_fill(0, $GLOBALS['maxLen'], 0);
 
// variable to check if a given state
// has been solved
$v = array_fill(0, $GLOBALS['maxLen'], 0);
 
// Function to find the maximum sum subsequence
// such that no two elements are adjacent
function maxSum($arr, $i, $n)
{
    // Base case
    if ($i >= $n)
        return 0;
 
    // To check if a state has
    // been solved
    if ($GLOBALS['v'][$i])
        return $GLOBALS['dp'][$i];
         
    $GLOBALS['v'][$i] = 1;
 
    // Required recurrence relation
    $GLOBALS['dp'][$i] = max(maxSum($arr, $i + 1, $n),
                $arr[$i] + maxSum($arr, $i + 2, $n));
 
    // Returning the value
    return $GLOBALS['dp'][$i];
}
 
    // Driver code
    $arr = array( 12, 9, 7, 33 );
 
    $n = count($arr);
 
    echo maxSum($arr, 0, $n);
 
    // This code is contributed by AnkitRai01
?>


Output

45



Time Complexity : O(n)
Auxiliary Space : O(10)

Efficient approach : Using DP Tabulation method ( Iterative approach )

The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.

Steps to solve this problem :

  • Create a DP of size N+1 to store the solution of the subproblems.
  • Initialize the DP  with base cases
  • Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP
  • Return the final solution stored in dp[n-1].

Implementation :

C++




#include <bits/stdc++.h>
using namespace std;
 
// Function to find the maximum sum subsequence
// such that no two elements are adjacent
int maxSum(int arr[], int n)
{
    // Base case
    if (n == 0)
        return 0;
    if (n == 1)
        return arr[0];
    if (n == 2)
        return max(arr[0], arr[1]);
 
    // DP table to store solutions to subproblems
    int dp[n];
 
    // Initializing base cases
    dp[0] = arr[0];
    dp[1] = max(arr[0], arr[1]);
 
    // Filling up the DP table using recurrence relation
    for (int i = 2; i < n; i++) {
        dp[i] = max(dp[i - 1], arr[i] + dp[i - 2]);
    }
 
    // Returning the final answer
    return dp[n - 1];
}
 
// Driver code
int main()
{
    int arr[] = { 12, 9, 7, 33 };
    int n = sizeof(arr) / sizeof(arr[0]);
    cout << maxSum(arr, n) << endl;
    return 0;
}


Java




import java.util.*;
 
public class Main {
    // Function to find the maximum sum subsequence
    // such that no two elements are adjacent
    public static int maxSum(int[] arr, int n)
    {
        // Base case
        if (n == 0)
            return 0;
        if (n == 1)
            return arr[0];
        if (n == 2)
            return Math.max(arr[0], arr[1]);
 
        // DP table to store solutions to subproblems
        int[] dp = new int[n];
 
        // Initializing base cases
        dp[0] = arr[0];
        dp[1] = Math.max(arr[0], arr[1]);
 
        // Filling up the DP table using recurrence relation
        for (int i = 2; i < n; i++) {
            dp[i] = Math.max(dp[i - 1], arr[i] + dp[i - 2]);
        }
 
        // Returning the final answer
        return dp[n - 1];
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int[] arr = { 12, 9, 7, 33 };
        int n = arr.length;
        System.out.println(maxSum(arr, n));
    }
}


Python3




def maxSum(arr, n):
    # Base case
    if n == 0:
        return 0
    if n == 1:
        return arr[0]
    if n == 2:
        return max(arr[0], arr[1])
 
    # DP table to store solutions to subproblems
    dp = [0] * n
 
    # Initializing base cases
    dp[0] = arr[0]
    dp[1] = max(arr[0], arr[1])
 
    # Filling up the DP table using recurrence relation
    for i in range(2, n):
        dp[i] = max(dp[i - 1], arr[i] + dp[i - 2])
 
    # Returning the final answer
    return dp[n - 1]
 
 
arr = [12, 9, 7, 33]
n = len(arr)
print(maxSum(arr, n))


C#




using System;
 
class GFG {
    // Function to find the maximum sum subsequence
    // such that no two elements are adjacent
    static int maxSum(int[] arr, int n)
    {
        // Base case
        if (n == 0)
            return 0;
        if (n == 1)
            return arr[0];
        if (n == 2)
            return Math.Max(arr[0], arr[1]);
 
        // DP table to store solutions to subproblems
        int[] dp = new int[n];
 
        // Initializing base cases
        dp[0] = arr[0];
        dp[1] = Math.Max(arr[0], arr[1]);
 
        // Filling up the DP table using recurrence relation
        for (int i = 2; i < n; i++) {
            dp[i] = Math.Max(dp[i - 1], arr[i] + dp[i - 2]);
        }
 
        // Returning the final answer
        return dp[n - 1];
    }
 
    // Driver code
    static void Main()
    {
        int[] arr = { 12, 9, 7, 33 };
        int n = arr.Length;
        Console.WriteLine(maxSum(arr, n));
    }
}


Javascript




// Function to find the maximum sum subsequence
// such that no two elements are adjacent
function maxSum(arr) {
    // Base cases
    const n = arr.length;
    if (n === 0)
        return 0;
    if (n === 1)
        return arr[0];
    if (n === 2)
        return Math.max(arr[0], arr[1]);
 
    // DP array to store solutions to subproblems
    const dp = new Array(n);
 
    // Initializing base cases
    dp[0] = arr[0];
    dp[1] = Math.max(arr[0], arr[1]);
 
    // Filling up the DP array using recurrence relation
    for (let i = 2; i < n; i++) {
        dp[i] = Math.max(dp[i - 1], arr[i] + dp[i - 2]);
    }
 
    // Returning the final answer
    return dp[n - 1];
}
 
// Driver code
const arr = [12, 9, 7, 33];
console.log(maxSum(arr));


Output

45



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

Another Approach(Using Greedy Strategy):

  1. Initialize include as the first element and exclude as 0.
  2. For each element in the array, update include as exclude + current element (considering the current element).
  3. Update exclude as the maximum of include and exclude (excluding the current element).
  4. Repeat steps 2 and 3 for all elements in the array.
  5. Finally, return the maximum of include and exclude as the maximum sum.

Below is the implementation of the above approach:  

C++




#include <iostream>
#include <algorithm>
using namespace std;
 
int maxSumNoAdjacent(int arr[], int n) {
    if (n == 0)
        return 0;
    if (n == 1)
        return arr[0];
 
    int include = arr[0];
    int exclude = 0;
 
    for (int i = 1; i < n; i++) {
        int prevInclude = include;
        include = exclude + arr[i];
        exclude = max(prevInclude, exclude);
    }
 
    return max(include, exclude);
}
 
int main() {
    int arr[] = {12, 9, 7, 33};
    int n = sizeof(arr) / sizeof(arr[0]);
 
    int maxSum = maxSumNoAdjacent(arr, n);
    cout<< maxSum << endl;
 
    return 0;
}


Java




import java.util.Arrays;
 
public class Main {
    public static int maxSumNoAdjacent(int[] arr, int n) {
        if (n == 0)
            return 0;
        if (n == 1)
            return arr[0];
        int include = arr[0];
        int exclude = 0;
        for (int i = 1; i < n; i++) {
            int prevInclude = include;
            include = exclude + arr[i];
            exclude = Math.max(prevInclude, exclude);
        }
        return Math.max(include, exclude);
    }
 
    public static void main(String[] args) {
        int[] arr = {12, 9, 7, 33};
        int n = arr.length;
        int maxSum = maxSumNoAdjacent(arr, n);
        System.out.println(maxSum);
    }
}


Python




def maxSumNoAdjacent(arr, n):
    if n == 0:
        return 0
    if n == 1:
        return arr[0]
    include = arr[0]
    exclude = 0
    for i in range(1, n):
        prevInclude = include
        include = exclude + arr[i]
        exclude = max(prevInclude, exclude)
    return max(include, exclude)
 
arr = [12, 9, 7, 33]
n = len(arr)
maxSum = maxSumNoAdjacent(arr, n)
print(maxSum)


C#




using System;
 
class Program
{
    static int MaxSumNoAdjacent(int[] arr, int n)
    {
        if (n == 0)
            return 0;
        if (n == 1)
            return arr[0];
        int include = arr[0];
        int exclude = 0;
        for (int i = 1; i < n; i++)
        {
            int prevInclude = include;
            include = exclude + arr[i];
            exclude = Math.Max(prevInclude, exclude);
        }
        return Math.Max(include, exclude);
    }
 
    static void Main()
    {
        int[] arr = { 12, 9, 7, 33 };
        int n = arr.Length;
        int maxSum = MaxSumNoAdjacent(arr, n);
        Console.WriteLine(maxSum);
    }
}


Javascript




function maxSumNoAdjacent(arr, n) {
    if (n === 0)
        return 0;
    if (n === 1)
        return arr[0];
    let include = arr[0];
    let exclude = 0;
    for (let i = 1; i < n; i++) {
        let prevInclude = include;
        include = exclude + arr[i];
        exclude = Math.max(prevInclude, exclude);
    }
    return Math.max(include, exclude);
}
 
let arr = [12, 9, 7, 33];
let n = arr.length;
let maxSum = maxSumNoAdjacent(arr, n);
console.log(maxSum);


PHP




<?php
function maxSumNoAdjacent($arr, $n) {
    if ($n == 0)
        return 0;
    if ($n == 1)
        return $arr[0];
    $include = $arr[0];
    $exclude = 0;
    for ($i = 1; $i < $n; $i++) {
        $prevInclude = $include;
        $include = $exclude + $arr[$i];
        $exclude = max($prevInclude, $exclude);
    }
    return max($include, $exclude);
}
$arr = [12, 9, 7, 33];
$n = count($arr);
$maxSum = maxSumNoAdjacent($arr, $n);
echo $maxSum . "\n";
?>


Output

45



Time Complexity :O(n), where n is the size of the input array. This is because the code iterates through the array once in the for loop, performing a constant number of operations for each element.
Auxiliary Space :  O(1), meaning it uses a constant amount of extra space. The space usage remains constant throughout the execution, regardless of the size of the input array. This is because the code only uses a few variables (include, exclude, prevInclude) to keep track of the maximum sum, and their space requirements do not depend on the size of the array.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads