Skip to content
Related Articles

Related Articles

Maximum possible sum of non-adjacent array elements not exceeding K
  • Difficulty Level : Basic
  • Last Updated : 05 May, 2021

Given an array arr[] consisting of N integers and an integer K, the task is to select some non-adjacent array elements with the maximum possible sum not exceeding K.

Examples:

Input: arr[] = {50, 10, 20, 30, 40}, K = 100
Output: 90
Explanation: To maximize the sum that doesn’t exceed K(= 100), select elements 50 and 40.
Therefore, maximum possible sum = 90.

Input: arr[] = {20, 10, 17, 12, 8, 9}, K = 64
Output: 46
Explanation: To maximize the sum that doesn’t exceed K(= 64), select elements 20, 17, and 9.
Therefore, maximum possible sum = 46.

Naive Approach: The simplest approach is to recursively generate all possible subsets of the given array and for each subset, check if it does not contain adjacent elements and has the sum not exceeding K. Among all subsets for which the above condition is found to be true, print the maximum sum obtained for any subset.



Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function to find the
// maximum sum not exceeding
// K possible by selecting
// a subset of non-adjacent elements
int maxSum(int a[],
           int n, int k)
{
  // Base Case
  if (n <= 0)
    return 0;
 
  // Not selecting current
  // element
  int option = maxSum(a,
                      n - 1, k);
 
  // If selecting current
  // element is possible
  if (k >= a[n - 1])
    option = max(option,
                 a[n - 1] +
             maxSum(a, n - 2,
                    k - a[n - 1]));
 
  // Return answer
  return option;
}
 
// Driver Code
int main()
{
  // Given array arr[]
  int arr[] = {50, 10,
               20, 30, 40};
 
  int N = sizeof(arr) /
          sizeof(arr[0]);
 
  // Given K
  int K = 100;
 
  // Function Call
  cout << (maxSum(arr,
                  N, K));
}
 
// This code is contributed by gauravrajput1

Java




// Java program for the above approach
 
import java.io.*;
 
class GFG {
 
    // Function to find the maximum sum
    // not exceeding K possible by selecting
    // a subset of non-adjacent elements
    public static int maxSum(
        int a[], int n, int k)
    {
        // Base Case
        if (n <= 0)
            return 0;
 
        // Not selecting current element
        int option = maxSum(a, n - 1, k);
 
        // If selecting current element
        // is possible
        if (k >= a[n - 1])
            option = Math.max(
                option,
                a[n - 1]
                    + maxSum(a, n - 2,
                             k - a[n - 1]));
 
        // Return answer
        return option;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        // Given array arr[]
        int arr[] = { 50, 10, 20, 30, 40 };
 
        int N = arr.length;
 
        // Given K
        int K = 100;
 
        // Function Call
        System.out.println(maxSum(arr, N, K));
    }
}

Python3




# Python3 program for the above approach
 
# Function to find the maximum sum
# not exceeding K possible by selecting
# a subset of non-adjacent elements
def maxSum(a, n, k):
     
    # Base Case
    if (n <= 0):
        return 0
 
    # Not selecting current element
    option = maxSum(a, n - 1, k)
 
    # If selecting current element
    # is possible
    if (k >= a[n - 1]):
        option = max(option, a[n - 1] +
        maxSum(a, n - 2, k - a[n - 1]))
 
    # Return answer
    return option
 
# Driver Code
if __name__ == '__main__':
     
    # Given array arr[]
    arr = [ 50, 10, 20, 30, 40 ]
 
    N = len(arr)
 
    # Given K
    K = 100
 
    # Function Call
    print(maxSum(arr, N, K))
 
# This code is contributed by mohit kumar 29

C#




// C# program for the
// above approach
using System;
class GFG{
 
// Function to find the maximum
// sum not exceeding K possible
// by selecting a subset of
// non-adjacent elements
public static int maxSum(int []a,
                         int n, int k)
{
  // Base Case
  if (n <= 0)
    return 0;
 
  // Not selecting current element
  int option = maxSum(a, n - 1, k);
 
  // If selecting current
  // element is possible
  if (k >= a[n - 1])
    option = Math.Max(option, a[n - 1] +
                      maxSum(a, n - 2,
                             k - a[n - 1]));
   
  // Return answer
  return option;
}
 
// Driver Code
public static void Main(String[] args)
{
  // Given array []arr
  int []arr = {50, 10, 20, 30, 40};
 
  int N = arr.Length;
 
  // Given K
  int K = 100;
 
  // Function Call
  Console.WriteLine(maxSum(arr, N, K));
}
}
 
// This code is contributed by Rajput-Ji

Javascript




<script>
 
// Javascript program for the
// above approach
 
// Function to find the maximum sum
// not exceeding K possible by selecting
// a subset of non-adjacent elements
function maxSum(a, n, k)
{
     
    // Base Case
    if (n <= 0)
        return 0;
 
    // Not selecting current element
    let option = maxSum(a, n - 1, k);
 
    // If selecting current element
    // is possible
    if (k >= a[n - 1])
        option = Math.max(option, a[n - 1] +
             maxSum(a, n - 2, k - a[n - 1]));
 
    // Return answer
    return option;
}
 
// Driver Code
 
// Given array arr[]
let arr = [ 50, 10, 20, 30, 40 ];
 
let N = arr.length;
 
// Given K
let K = 100;
 
// Function Call
document.write(maxSum(arr, N, K));
 
// This code is contributed by target_2 
 
</script>
Output
90

Time Complexity: O(2N)
Auxiliary Space: O(N)

Efficient Approach: To optimize the above approach, the idea is to use Dynamic Programming. Two possible options exist for every array element:

  1. Either skip the current element and proceed to the next element.
  2. Select the current element only if it is smaller than or equal to K.

Follow the steps below to solve the problem:

  1. Initialize an array dp[N][K+1] with -1 where dp[i][j] will store the maximum sum to make sum j using elements up to index i.
  2. From the above transition, find the maximum sums if the current element gets picked and if it is not picked, recursively.
  3. Store the minimum answer for the current state.
  4. Also, add the base condition that if the current state (i, j) is already visited i.e., dp[i][j]!=-1 return dp[i][j].
  5. Print dp[N][K] as the maximum possible sum.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Initialize dp
int dp[1005][1005];
 
// Function find the maximum sum that
// doesn't exceeds K by choosing elements
int maxSum(int* a, int n, int k)
{
     
    // Base Case
    if (n <= 0)
        return 0;
 
    // Return the memoized state
    if (dp[n][k] != -1)
        return dp[n][k];
 
    // Dont pick the current element
    int option = maxSum(a, n - 1, k);
 
    // Pick the current element
    if (k >= a[n - 1])
        option = max(option,
                     a[n - 1] +
             maxSum(a, n - 2,
                 k - a[n - 1]));
 
    // Return and store the result
    return dp[n][k] = option;
}
 
// Driver Code
int main()
{
    int N = 5;
 
    int arr[] = { 50, 10, 20, 30, 40 };
 
    int K = 100;
 
    // Fill dp array with -1
    memset(dp, -1, sizeof(dp));
 
    // Print answer
    cout << maxSum(arr, N, K) << endl;
}
 
// This code is contributed by bolliranadheer

Java




// Java program for the above approach
 
import java.util.*;
 
class GFG {
 
    // Function find the maximum sum that
    // doesn't exceeds K by choosing elements
    public static int maxSum(int a[], int n,
                             int k, int[][] dp)
    {
        // Base Case
        if (n <= 0)
            return 0;
 
        // Return the memoized state
        if (dp[n][k] != -1)
            return dp[n][k];
 
        // Dont pick the current element
        int option = maxSum(a, n - 1,
                            k, dp);
 
        // Pick the current element
        if (k >= a[n - 1])
            option = Math.max(
                option,
                a[n - 1]
                    + maxSum(a, n - 2,
                             k - a[n - 1],
                             dp));
 
        // Return and store the result
        return dp[n][k] = option;
    }
 
    // Driver Code
    public static void main(String[] args)
    {
        int arr[] = { 50, 10, 20, 30, 40 };
 
        int N = arr.length;
 
        int K = 100;
 
        // Initialize dp
        int dp[][] = new int[N + 1][K + 1];
 
        for (int i[] : dp) {
            Arrays.fill(i, -1);
        }
        // Print answer
        System.out.println(maxSum(arr, N, K, dp));
    }
}

Python3




# Python3 program for the
# above approach
 
# Function find the maximum
# sum that doesn't exceeds K
# by choosing elements
def maxSum(a, n, k, dp):
   
    # Base Case
    if (n <= 0):
        return 0;
 
    # Return the memoized state
    if (dp[n][k] != -1):
        return dp[n][k];
 
    # Dont pick the current
    # element
    option = maxSum(a, n - 1,
                    k, dp);
 
    # Pick the current element
    if (k >= a[n - 1]):
        option = max(option, a[n - 1] +
                 maxSum(a, n - 2,
                        k - a[n - 1], dp));
    dp[n][k] = option;
     
    # Return and store
    # the result
    return dp[n][k];
 
# Driver Code
if __name__ == '__main__':
   
    arr = [50, 10, 20,
           30, 40];
    N = len(arr);
    K = 100;
    # Initialize dp
    dp = [[-1 for i in range(K + 1)]
              for j in range(N + 1)]
 
    # Pranswer
    print(maxSum(arr, N,
                 K, dp));
 
# This code is contributed by shikhasingrajput

C#




// C# program for the
// above approach
using System;
class GFG{
 
// Function find the maximum
// sum that doesn't exceeds K
// by choosing elements
public static int maxSum(int []a, int n,
                         int k, int[,] dp)
{
  // Base Case
  if (n <= 0)
    return 0;
 
  // Return the memoized
  // state
  if (dp[n, k] != -1)
    return dp[n, k];
 
  // Dont pick the current
  // element
  int option = maxSum(a, n - 1,
                      k, dp);
 
  // Pick the current element
  if (k >= a[n - 1])
    option = Math.Max(option, a[n - 1] +
                      maxSum(a, n - 2,
                             k - a[n - 1],
                             dp));
 
  // Return and store the
  // result
  return dp[n, k] = option;
}
 
// Driver Code
public static void Main(String[] args)
{
  int []arr = {50, 10, 20, 30, 40};
  int N = arr.Length;
  int K = 100;
   
  // Initialize dp
  int [,]dp = new int[N + 1,
                      K + 1];
 
  for (int j = 0; j < N + 1; j++)
  {
    for (int k = 0; k < K + 1; k++)
      dp[j, k] = -1;
  }
   
  // Print answer
  Console.WriteLine(maxSum(arr, N,
                           K, dp));
}
}
 
// This code is contributed by Rajput-Ji

Javascript




<script>
 
// Javascript program to implement
// the above approach
 
    // Function find the maximum sum that
    // doesn't exceeds K by choosing elements
    function maxSum(a, n, k, dp)
    {
        // Base Case
        if (n <= 0)
            return 0;
 
        // Return the memoized state
        if (dp[n][k] != -1)
            return dp[n][k];
 
        // Dont pick the current element
        let option = maxSum(a, n - 1,
                            k, dp);
 
        // Pick the current element
        if (k >= a[n - 1])
            option = Math.max(
                option,
                a[n - 1]
                    + maxSum(a, n - 2,
                             k - a[n - 1],
                             dp));
 
        // Return and store the result
        return dp[n][k] = option;
    }
 
// Driver Code
 
 // Given array
  let arr = [ 50, 10, 20, 30, 40 ];
 
        let N = arr.length;
 
        let K = 100;
 
        // Initialize dp
        let dp = new Array(N + 1);
        // Loop to create 2D array using 1D array
        for (var i = 0; i < 1000; i++) {
            dp[i] = new Array(2);
        }
 
       for (var i = 0; i < 1000; i++) {
            for (var j = 0; j < 1000; j++) {
            dp[i][j] = -1;
        }
        }
        // Prlet answer
        document.write(maxSum(arr, N, K, dp));
          
</script>
Output
90

Time Complexity: O(N*K), where N is the size of the given array and K is the limit.
Auxiliary Space: O(N)

Attention reader! Don’t stop learning now. Get hold of all the important mathematical concepts for competitive programming with the Essential Maths for CP Course at a student-friendly price. To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

My Personal Notes arrow_drop_up
Recommended Articles
Page :