Open In App

Maximum sum such that exactly half of the elements are selected and no two adjacent

Last Updated : 03 Jun, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array A containing N integers. Find the maximum sum possible such that exact floor(N/2) elements are selected and no two selected elements are adjacent to each other. (if N = 5, then exactly 2 elements should be selected as floor(5/2) = 2) 
For a simpler version of this problem check out this.

Examples:

Input: A = [1, 2, 3, 4, 5, 6] 
Output: 12 
Explanation: 
Select 2, 4 and 6 making the sum 12.

Input : A = [-1000, -100, -10, 0, 10] 
Output :
Explanation: 
Select -10 and 10, making the sum 0. 

Approach:  

  • We will use the concept of dynamic programming. The following is how the dp states are defined:

dp[i][j] = maximum sum till index i such that j elements are selected 

  • Since no two adjacent elements can be selected :

dp[i][j] = max(a[i] + dp[i-2][j-1], dp[i-1][j])  

Below is the implementation of the above approach. 

C++




// C++ program to find maximum sum possible
// such that exactly floor(N/2) elements
// are selected and no two selected
// elements are adjacent to each other
#include <bits/stdc++.h>
using namespace std;
 
// Function return the maximum sum
// possible under given condition
int MaximumSum(int a[], int n)
{
    int dp[n + 1][n + 1];
 
    // Intitialising the dp table
    for (int i = 0; i < n + 1; i++)
    {
        for (int j = 0; j < n + 1; j++)
            dp[i][j] = INT_MIN;
    }
 
    // Base case
    for (int i = 0; i < n + 1; i++)
        dp[i][0] = 0;
 
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= i; j++)
        {
            int val = INT_MIN;
 
            // Condition to select the current
            // element
            if ((i - 2 >= 0
                 && dp[i - 2][j - 1] != INT_MIN)
                                   || i - 2 < 0)
            {
                val = a[i - 1] +
                    (i - 2 >= 0 ?
                     dp[i - 2][j - 1] : 0);
            }
             
            // Condition to not select the
            // current element if possible
            if (i - 1 >= j)
            {
                val = max(val, dp[i - 1][j]);
            }
            dp[i][j] = val;
        }
    }
 
    return dp[n][n / 2];
}
 
//Driver code
int main()
{
     
    int A[] = {1, 2, 3, 4, 5, 6};
     
    int N = sizeof(A) / sizeof(A[0]);
 
    cout << MaximumSum(A, N);
 
    return 0;
}


Java




// Java program to find maximum sum possible
// such that exactly Math.floor(N/2) elements
// are selected and no two selected
// elements are adjacent to each other
class GFG{
 
// Function return the maximum sum
// possible under given condition
static int MaximumSum(int a[], int n)
{
    int [][]dp = new int[n + 1][n + 1];
 
    // Intitialising the dp table
    for(int i = 0; i < n + 1; i++)
    {
       for(int j = 0; j < n + 1; j++)
          dp[i][j] = Integer.MIN_VALUE;
    }
 
    // Base case
    for(int i = 0; i < n + 1; i++)
       dp[i][0] = 0;
 
    for(int i = 1; i <= n; i++)
    {
       for(int j = 1; j <= i; j++)
       {
          int val = Integer.MIN_VALUE;
           
          // Condition to select the current
          // element
          if ((i - 2 >= 0 &&
            dp[i - 2][j - 1] != Integer.MIN_VALUE) ||
               i - 2 < 0)
          {
              val = a[i - 1] + (i - 2 >= 0 ?
                             dp[i - 2][j - 1] : 0);
          }
           
          // Condition to not select the
          // current element if possible
          if (i - 1 >= j)
          {
              val = Math.max(val, dp[i - 1][j]);
          }
          dp[i][j] = val;
        }
    }
    return dp[n][n / 2];
}
 
// Driver code
public static void main(String[] args)
{
    int A[] = { 1, 2, 3, 4, 5, 6 };
    int N = A.length;
 
    System.out.print(MaximumSum(A, N));
}
}
 
// This code is contributed by Rajput-Ji


Python3




# Python3 program to find maximum sum possible
# such that exactly floor(N/2) elements
# are selected and no two selected
# elements are adjacent to each other
 
import sys
# Function return the maximum sum
# possible under given condition
def MaximumSum(a,n):
    dp = [[0 for i in range(n+1)] for j in range(n+1)]
 
    # Intitialising the dp table
    for i in range(n + 1):
        for j in range(n + 1):
            dp[i][j] = -sys.maxsize-1
 
    # Base case
    for i in range(n+1):
        dp[i][0] = 0
 
    for i in range(1,n+1,1):
        for j in range(1,i+1,1):
            val = -sys.maxsize-1
 
            # Condition to select the current
            # element
            if ((i - 2 >= 0 and dp[i - 2][j - 1] != -sys.maxsize-1) or i - 2 < 0):
                if (i - 2 >= 0):
                    val = a[i - 1] + dp[i - 2][j - 1]
                else:
                    val = a[i - 1]
             
            # Condition to not select the
            # current element if possible
            if (i - 1 >= j):
                val = max(val, dp[i - 1][j])
             
            dp[i][j] = val
 
    return dp[n][n // 2]
 
#Driver code
if __name__ == '__main__':
    A = [1, 2, 3, 4, 5, 6]
     
    N = len(A)
 
    print(MaximumSum(A,N))
 
# This code is contributed by Bhupendra_Singh


C#




// C# program to find maximum sum possible
// such that exactly Math.floor(N/2) elements
// are selected and no two selected
// elements are adjacent to each other
using System;
 
class GFG{
 
// Function return the maximum sum
// possible under given condition
static int MaximumSum(int []a, int n)
{
    int [,]dp = new int[n + 1, n + 1];
 
    // Intitialising the dp table
    for(int i = 0; i < n + 1; i++)
    {
       for(int j = 0; j < n + 1; j++)
          dp[i, j] = Int32.MinValue;
    }
 
    // Base case
    for(int i = 0; i < n + 1; i++)
       dp[i, 0] = 0;
 
    for(int i = 1; i <= n; i++)
    {
       for(int j = 1; j <= i; j++)
       {
          int val = Int32.MinValue;
           
          // Condition to select the current
          // element
          if ((i - 2 >= 0 &&
            dp[i - 2, j - 1] != Int32.MinValue) ||
               i - 2 < 0)
          {
              val = a[i - 1] + (i - 2 >= 0 ?
                             dp[i - 2, j - 1] : 0);
          }
           
          // Condition to not select the
          // current element if possible
          if (i - 1 >= j)
          {
              val = Math.Max(val, dp[i - 1, j]);
          }
          dp[i, j] = val;
       }
    }
    return dp[n, n / 2];
}
 
// Driver code
public static void Main()
{
    int []A = { 1, 2, 3, 4, 5, 6 };
    int N = A.Length;
 
    Console.Write(MaximumSum(A, N));
}
}
 
// This code is contributed by Nidhi_biet


Javascript




<script>
 
// JavaScript program to find maximum sum possible
// such that exactly Math.floor(N/2) elements
// are selected and no two selected
// elements are adjacent to each other
 
 
// Function return the maximum sum
// possible under given condition
function MaximumSum(a,n)
{
    let dp = [];
 
    for(let i=0;i<n+1;i++) dp.push(Array(n+1));
 
    // Intitialising the dp table
    for(let i = 0; i < n + 1; i++)
    {
       for(let j = 0; j < n + 1; j++)
          dp[i][j] = -10000;
    }
 
    // Base case
    for(let i = 0; i < n + 1; i++)
       dp[i][0] = 0;
 
    for(let i = 1; i <= n; i++)
    {
       for(let j = 1; j <= i; j++)
       {
          let val = -10000;
           
          // Condition to select the current
          // element
          if ((i - 2 >= 0 &&
            dp[i - 2, j - 1] != -10000) ||
               i - 2 < 0)
          {
              val = a[i - 1] + (i - 2 >= 0 ?
                             dp[i - 2][j - 1] : 0);
          }
           
          // Condition to not select the
          // current element if possible
          if (i - 1 >= j)
          {
              val = Math.max(val, dp[i - 1][j]);
          }
          dp[i][j] = val;
       }
    }
    return dp[n][n / 2]
}
 
// Driver code
 
let A = [1, 2, 3, 4, 5, 6];
let N = A.length;
 
document.write(MaximumSum(A, N));
 
// This code is contributed by Nidhi_biet
 
</script>


Output: 

12

 

Time Complexity : O(N2)
 

Efficient Approach  

  • We will use dynamic programming but with slightly modified states. Storing both the index and is number of elements taken till now are futile since we always need to take exact floor(i/2) elements, so at i’th position for the dp storage we will assume floor(i/2) elements in the subset till now.
  • The following is the dp table states:

dp[i][1] = maximum sum till i’th index, picking element a[i], with floor(i/2) elements, none adjacent to each other. 
dp[i][0] = maximum sum till i’th index, not picking element a[i], with floor(i/2) elements, none adjacent to each other. 

  • We have two cases : 
    • When i is odd : If we have to pick a[i], then we can’t pick a[i-1], so the only options left are (i – 2)th and (i – 3) rd state (because floor((i – 2)/2) = floor((i – 3)/2) = floor(i/2) – 1, and since we pick a[i], total picked elements will be floor(i/2) ). If we don’t pick a[i], then a sum will be formed by taking a[i-1] and using states i – 1, i – 2 and i – 3 or a[i – 2] using state i – 3 as these will only give the total of floor(i/2).

dp[i][1] = arr[i] + max({dp[i – 3][1], dp[i – 3][0], dp[i – 2][1], dp[i – 2][0]}) 
dp[i][0] = max({arr[i – 1] + dp[i – 2][0], arr[i – 1] + dp[i – 3][1], arr[i – 1] + dp[i – 3][0], 
arr[i – 2] + dp[i – 3][0]})  

  • When i is even : If we pick a[i], then using states i – 1 and i – 2, else picking a[i – 1] and using state i – 2. 
     

dp[i][1] = arr[i] + max({dp[i – 2][1], dp[i – 2][0], dp[i – 1][0]}) 
dp[i][0] = arr[i – 1] + dp[i – 2][0] 

Below is the implementation of the above approach.  

C++




// C++ program to find maximum sum possible
// such that exactly floor(N/2) elements
// are selected and no two selected
// elements are adjacent to each other
#include <bits/stdc++.h>
using namespace std;
 
// Function return the maximum sum
// possible under given condition
int MaximumSum(int a[], int n)
{
 
    int dp[n + 1][2];
     
    // Intitialising the dp table
    memset(dp, 0, sizeof(dp));
 
    // Base case
    dp[2][1] = a[1];
    dp[2][0] = a[0];
 
    for (int i = 3; i < n + 1; i++) {
        // When i is odd
        if (i & 1) {
            int temp = max({ dp[i - 3][1],
                             dp[i - 3][0],
                             dp[i - 2][1],
                             dp[i - 2][0] });
             
            dp[i][1] = a[i - 1] + temp;
            dp[i][0] = max({ a[i - 2] + dp[i - 2][0],
                             a[i - 2] + dp[i - 3][1],
                             a[i - 2] + dp[i - 3][0],
                             a[i - 3] + dp[i - 3][0] });
        }
 
        // When i is even
        else {
            dp[i][1] = a[i - 1] + max({ dp[i - 2][1],
                                        dp[i - 2][0],
                                        dp[i - 1][0] });
             
            dp[i][0] = a[i - 2] + dp[i - 2][0];
        }
    }
    // Maximum of if we pick last element or not
    return max(dp[n][1], dp[n][0]);
}
 
// Driver code
int main()
{
    int A[] = {1, 2, 3, 4, 5, 6};
     
    int N = sizeof(A) / sizeof(A[0]);
 
    cout << MaximumSum(A, N);
 
    return 0;
}


Java




// Java program to find maximum sum possible
// such that exactly Math.floor(N/2) elements
// are selected and no two selected
// elements are adjacent to each other
import java.util.*;
 
class GFG{
 
// Function return the maximum sum
// possible under given condition
static int MaximumSum(int a[], int n)
{
 
    int [][]dp = new int[n + 1][2];
 
    // Base case
    dp[2][1] = a[1];
    dp[2][0] = a[0];
 
    for(int i = 3; i < n + 1; i++)
    {
        
       // When i is odd
       if (i % 2 == 1)
       {
           int temp = Math.max((Math.max(dp[i - 3][1],
                                         dp[i - 3][0])),
                                Math.max(dp[i - 2][1],
                                         dp[i - 2][0]));
           dp[i][1] = a[i - 1] + temp;
           dp[i][0] = Math.max((Math.max(a[i - 2] +
                                        dp[i - 2][0],
                                         a[i - 2] +
                                        dp[i - 3][1])),
                                Math.max(a[i - 2] +
                                        dp[i - 3][0],
                                         a[i - 3] +
                                        dp[i - 3][0]));
       }
        
       // When i is even
       else
       {
           dp[i][1] = a[i - 1] + (Math.max((
                                  Math.max(dp[i - 2][1],
                                           dp[i - 2][0])),
                                           dp[i - 1][0]));
           dp[i][0] = a[i - 2] + dp[i - 2][0];
       }
    }
     
    // Maximum of if we pick last element or not
    return Math.max(dp[n][1], dp[n][0]);
}
 
static int max(int []arr)
{
    return 1;
}
 
// Driver code
public static void main(String[] args)
{
    int A[] = {1, 2, 3, 4, 5, 6};
    int N = A.length;
 
    System.out.print(MaximumSum(A, N));
}
}
 
// This code is contributed by Rajput-Ji


Python3




# Python3 program to find maximum sum possible
# such that exactly floor(N/2) elements
# are selected and no two selected
# elements are adjacent to each other
 
# Function return the maximum sum
# possible under given condition
def MaximumSum(a, n):
 
    dp = [[0 for x in range (2)]
             for y in range(n + 1)]
     
    # Base case
    dp[2][1] = a[1]
    dp[2][0] = a[0]
 
    for i in range (3, n + 1):
       
        # When i is odd
        if (i & 1):
            temp = max([dp[i - 3][1],
                        dp[i - 3][0],
                        dp[i - 2][1],
                        dp[i - 2][0]])
             
            dp[i][1] = a[i - 1] + temp
            dp[i][0] = max([a[i - 2] + dp[i - 2][0],
                            a[i - 2] + dp[i - 3][1],
                            a[i - 2] + dp[i - 3][0],
                            a[i - 3] + dp[i - 3][0]])
 
        # When i is even
        else:
            dp[i][1] = (a[i - 1] + max([dp[i - 2][1],
                                        dp[i - 2][0],
                                        dp[i - 1][0]]))
             
            dp[i][0] = a[i - 2] + dp[i - 2][0]
       
    # Maximum of if we pick last
    # element or not
    return max(dp[n][1], dp[n][0])
 
# Driver code
if __name__ == "__main__"
   
    A = [1, 2, 3, 4, 5, 6]   
    N = len(A)
    print(MaximumSum(A, N))
 
# This code is contributed by Chitranayal


C#




// C# program to find maximum sum possible
// such that exactly Math.Floor(N/2) elements
// are selected and no two selected
// elements are adjacent to each other
using System;
 
class GFG{
 
// Function return the maximum sum
// possible under given condition
static int MaximumSum(int []a, int n)
{
    int [,]dp = new int[n + 1, 2];
 
    // Base case
    dp[2, 1] = a[1];
    dp[2, 0] = a[0];
 
    for(int i = 3; i < n + 1; i++)
    {
 
       // When i is odd
       if (i % 2 == 1)
       {
           int temp = Math.Max((Math.Max(dp[i - 3, 1],
                                         dp[i - 3, 0])),
                                Math.Max(dp[i - 2, 1],
                                         dp[i - 2, 0]));
           dp[i, 1] = a[i - 1] + temp;
           dp[i, 0] = Math.Max((Math.Max(a[i - 2] +
                                        dp[i - 2, 0],
                                         a[i - 2] +
                                        dp[i - 3, 1])),
                                Math.Max(a[i - 2] +
                                        dp[i - 3, 0],
                                         a[i - 3] +
                                        dp[i - 3, 0]));
       }
        
       // When i is even
       else
       {
           dp[i, 1] = a[i - 1] + (Math.Max((
                                  Math.Max(dp[i - 2, 1],
                                           dp[i - 2, 0])),
                                           dp[i - 1, 0]));
           dp[i, 0] = a[i - 2] + dp[i - 2, 0];
       }
    }
     
    // Maximum of if we pick last element or not
    return Math.Max(dp[n, 1], dp[n, 0]);
}
 
static int max(int []arr)
{
    return 1;
}
 
// Driver code
public static void Main(String[] args)
{
    int []A = { 1, 2, 3, 4, 5, 6 };
    int N = A.Length;
 
    Console.Write(MaximumSum(A, N));
}
}
 
// This code is contributed by 29AjayKumar


Javascript




<script>
 
// Javascript program to find maximum sum possible
// such that exactly floor(N/2) elements
// are selected and no two selected
// elements are adjacent to each other
 
// Function return the maximum sum
// possible under given condition
function MaximumSum(a, n)
{
 
    var dp = Array.from(Array(n+1), ()=>Array(2).fill(0));
 
    // Base case
    dp[2][1] = a[1];
    dp[2][0] = a[0];
 
    for (var i = 3; i < n + 1; i++) {
        // When i is odd
        if (i & 1) {
            var temp = ([dp[i - 3][1],
                             dp[i - 3][0],
                             dp[i - 2][1],
                             dp[i - 2][0] ].reduce((a,b)=>
                               Math.max(a,b)));
             
            dp[i][1] = a[i - 1] + temp;
            dp[i][0] = ([ a[i - 2] + dp[i - 2][0],
                             a[i - 2] + dp[i - 3][1],
                             a[i - 2] + dp[i - 3][0],
                             a[i - 3] + dp[i - 3][0] ].reduce((a,b)=>
                               Math.max(a,b)));
        }
 
        // When i is even
        else {
            dp[i][1] = a[i - 1] + ([ dp[i - 2][1],
                                        dp[i - 2][0],
                                        dp[i - 1][0] ].reduce((a,b)=>
                                          Math.max(a,b)));
             
            dp[i][0] = a[i - 2] + dp[i - 2][0];
        }
    }
    // Maximum of if we pick last element or not
    return Math.max(dp[n][1], dp[n][0]);
}
 
// Driver code
var A = [1, 2, 3, 4, 5, 6];
 
var N = A.length;
document.write( MaximumSum(A, N));
 
 
</script>


Output: 

12

 

Time Complexity: O(N)



Similar Reads

Maximize sum of K elements selected from a Matrix such that each selected element must be preceded by selected row elements
Given a 2D array arr[][] of size N * M, and an integer K, the task is to select K elements with maximum possible sum such that if an element arr[i][j] is selected, then all the elements from the ith row present before the jth column needs to be selected. Examples: Input: arr[][] = {{10, 10, 100, 30}, {80, 50, 10, 50}}, K = 5Output: 250Explanation:S
10 min read
Reorder an array such that sum of left half is not equal to sum of right half
Given an array arr[] of even length, the task is to check whether is it possible to reorder the array element such that the sum of the left half is not equal to the sum of the right half of the array. If it is possible then print "Yes" with the reordered sequence else print "No". Examples: Input: arr[] = {1, 2, 2, 1, 3, 1} Output: Yes 1 1 1 2 2 3 E
5 min read
Find a permutation of 1 to N, such that A is minimum in left half and B is maximum in right half
Given three integers N, A, and B, the task is to find a permutation of pairwise distinct numbers from 1 to N such that A is the minimum element of the left half and B is the maximum element of the right half. It is also given that N is even. If no such permutations exist print -1. Examples: Input: N = 6, A = 2, B = 5Output: 6, 2, 4, 3, 5, 1Explanat
18 min read
Sum of elements in range L-R where first half and second half is filled with odd and even numbers
Given a number N, create an array such the first half of the array is filled with odd numbers till N, and the second half of the array is filled with even numbers. Also given are L and R indices, the task is to print the sum of elements in the array in the range [L, R]. Examples: Input: N = 12, L = 1, R = 11 Output: 66 The array formed thus is {1,
23 min read
Find the sum of the first half and second half elements of an array
Given an array arr of size N. The task is to find the sum of the first half (N/2) elements and the second half elements (N - N/2) of an array. Examples: Input : arr[] = {20, 30, 60, 10, 25, 15, 40} Output : 110, 90 Sum of first N/2 elements 20 + 30 + 60 is 110Input : arr[] = {50, 35, 20, 15} Output : 85, 35 Approach: Initialize SumFirst and SumSeco
10 min read
Minimize operations to reduce Array sum by half by reducing any elements by half
Given an array Arr[], the task is to find out the minimum number of operations to make the sum of array elements lesser or equal to half of its initial value. In one such operation, it is allowed to half the value of any array element. Examples: Input: Arr[] = [4, 6, 3, 9, 10, 2]Output: 5Explanation: The initial sum = (4+6+3+9+10+2) = 341st step: c
5 min read
Check if X and Y elements can be selected from two arrays respectively such that the maximum in X is less than the minimum in Y
Given two arrays arr1[] and arr2[] consisting of N and M integers respectively, and two integers X and Y, the task is to check if it is possible to choose X elements from arr1[] and Y elements from arr2[] such that the largest among these X elements is less than the minimum element among these Y elements. If it is possible, then print "Yes". Otherw
15 min read
Check if sum of digits in the left half is divisible by sum of digits in the right half in the largest permutation of N
Given a positive integer N, the task is to maximize the integer N by rearranging the digits and check if the sum of the left half digits is divisible by the sum of the right half digits or not. If found to be true, then print "Yes". Otherwise, print "No". If the number of digits(say D) in the given number N is odd, then consider any of the two poss
8 min read
Check if array sum of first half is divisible by sum of other half or vice versa
Given an array arr[] of size N, the task is to check if the sum of the left subarray is divisible by the sum of the right subarray or vice-versa. Print Yes if it was, otherwise No. Here, the left subarray will contain the string from 0 to mid=(N-1)/2 and the right subarray will contain the string from mid+1 to N-1. Example: Input: arr[] = [1, 2, 3,
5 min read
Maximum sum in an array such that every element has exactly one adjacent element to it
Given an array arr[] of N integers, you can select some indexes such that every selected index has exactly one other selected index adjacent to it and the sum of elements at the chosen indexes should be maximum. In other words, the task is to select elements from an array such that a single element alone is not selected and elements at three consec
9 min read