Maximum possible sum of non-adjacent array elements not exceeding K

01 Jul, 2022
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 = 100Output: 90Explanation: 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 = 64Output: 46Explanation: 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++
Java
Python3
C#
Javascript
// 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 elementsint 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 Codeint 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 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 program for the above approach # Function to find the maximum sum# not exceeding K possible by selecting# a subset of non-adjacent elementsdef 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 Codeif __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# program for the// above approachusing System;class GFG{ // Function to find the maximum// sum not exceeding K possible// by selecting a subset of// non-adjacent elementspublic 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 Codepublic 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
<script> // Javascript program for the// above approach // Function to find the maximum sum// not exceeding K possible by selecting// a subset of non-adjacent elementsfunction 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 Klet K = 100; // Function Calldocument.write(maxSum(arr, N, K)); // This code is contributed by target_2  </script>
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:
Either skip the current element and proceed to the next element.Select the current element only if it is smaller than or equal to K.
Either skip the current element and proceed to the next element.
Select the current element only if it is smaller than or equal to K.
Follow the steps below to solve the problem:
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.From the above transition, find the maximum sums if the current element gets picked and if it is not picked, recursively.Store the minimum answer for the current state.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].Print dp[N][K] as the maximum possible sum.
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.
From the above transition, find the maximum sums if the current element gets picked and if it is not picked, recursively.
Store the minimum answer for the current state.
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].
Print dp[N][K] as the maximum possible sum.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program for the above approach#include <bits/stdc++.h>using namespace std; // Initialize dpint dp[1005][1005]; // Function find the maximum sum that// doesn't exceeds K by choosing elementsint 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 Codeint 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 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 program for the# above approach # Function find the maximum# sum that doesn't exceeds K# by choosing elementsdef 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 Codeif __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)]     # Print answer    print(maxSum(arr, N,                 K, dp)); # This code is contributed by shikhasingrajput
// C# program for the// above approachusing System;class GFG{ // Function find the maximum// sum that doesn't exceeds K// by choosing elementspublic 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 Codepublic 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
<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;        }        }        // Print answer        document.write(maxSum(arr, N, K, dp));          </script>
90
Time Complexity: O(N*K), where N is the size of the given array and K is the limit.Auxiliary Space: O(N)
Rajput-Ji
mohit kumar 29
GauravRajput1
shikhasingrajput
bolliranadheer
target_2
avijitmondal1998
Kirti_Mangal
surinderdawra388
Arrays
Combinatorial
Dynamic Programming
Hash
Mathematical
Recursion
Arrays
Hash
Dynamic Programming
Mathematical
Recursion
Combinatorial
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Introduction to Data Structures
Window Sliding Technique
Search, insert and delete in an unsorted array
What is Data Structure: Types, Classifications and Applications
Chocolate Distribution Problem
Write a program to print all permutations of a given string
Permutation and Combination in Python
Factorial of a large number
Count of subsets with sum equal to X
itertools.combinations() module in Python to print all possible combinations