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++ 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 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 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# 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 |
<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> |
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.
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.
Below is the implementation of the above approach:
// 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 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 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 )]
# Print answer
print (maxSum(arr, N,
K, dp));
# This code is contributed by shikhasingrajput |
// 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 |
<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*K)
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 table DP to store the solution of the subproblems.
- Initialize the table 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
Implementation :
// C++ program for above approach #include <bits/stdc++.h> using namespace std;
// Function to find the maximum sum that // doesn't exceed K by choosing elements int maxSum( int * a, int n, int k)
{ // Initialize the DP table
int dp[n + 1][k + 1];
memset (dp, 0, sizeof (dp));
// Fill the DP table in bottom-up manner
for ( int i = 1; i <= n; i++) {
for ( int j = 1; j <= k; j++) {
// Don't pick the current element
dp[i][j] = dp[i - 1][j];
// Pick the current element
if (j >= a[i - 1]) {
dp[i][j] = max(
dp[i][j],
a[i - 1] + dp[i - 2][j - a[i - 1]]);
}
}
}
// Return the maximum sum
return dp[n][k];
} // Driver Code int main()
{ int N = 5;
int arr[] = { 50, 10, 20, 30, 40 };
int K = 100;
// Print answer
cout << maxSum(arr, N, K) << endl;
return 0;
} // this code is contributed by bhardwajji |
import java.util.*;
public class Main {
// Function to find the maximum sum that
// doesn't exceed K by choosing elements
public static int maxSum( int [] a, int n, int k) {
// Initialize the DP table
int [][] dp = new int [n + 1 ][k + 1 ];
for ( int [] row : dp) {
Arrays.fill(row, 0 );
}
// Fill the DP table in bottom-up manner
for ( int i = 1 ; i <= n; i++) {
for ( int j = 1 ; j <= k; j++) {
// Don't pick the current element
dp[i][j] = dp[i - 1 ][j];
// Pick the current element
if (j >= a[i - 1 ]) {
dp[i][j] = Math.max(
dp[i][j],
a[i - 1 ] + ((i >= 2 ) ? dp[i - 2 ][j - a[i - 1 ]] : 0 ));
}
}
}
// Return the maximum sum
return dp[n][k];
}
// Driver code
public static void main(String[] args) {
int N = 5 ;
int [] arr = { 50 , 10 , 20 , 30 , 40 };
int K = 100 ;
// Print answer
System.out.println(maxSum(arr, N, K));
}
} |
# Python3 program to find the maximum sum that # doesn't exceed K by choosing elements def maxSum(a, n, k):
# Initialize the DP table
dp = [[ 0 for i in range (k + 1 )] for j in range (n + 1 )]
# Fill the DP table in bottom-up manner
for i in range ( 1 , n + 1 ):
for j in range ( 1 , k + 1 ):
# Don't pick the current element
dp[i][j] = dp[i - 1 ][j]
# Pick the current element
if j > = a[i - 1 ]:
dp[i][j] = max (dp[i][j], a[i - 1 ] + dp[i - 2 ][j - a[i - 1 ]])
# Return the maximum sum
return dp[n][k]
# Driver Code if __name__ = = "__main__" :
N = 5
arr = [ 50 , 10 , 20 , 30 , 40 ]
K = 100
# Print answer
print (maxSum(arr, N, K))
|
using System;
public class GFG {
// Function to find the maximum sum that
// doesn't exceed K by choosing elements
public static int maxSum( int [] a, int n, int k)
{
// Initialize the DP table
int [, ] dp = new int [n + 1, k + 1];
for ( int i = 0; i <= n; i++) {
for ( int j = 0; j <= k; j++) {
dp[i, j] = 0;
}
}
// Fill the DP table in bottom-up manner
for ( int i = 1; i <= n; i++) {
for ( int j = 1; j <= k; j++) {
// Don't pick the current element
dp[i, j] = dp[i - 1, j];
// Pick the current element
if (j >= a[i - 1]) {
dp[i, j] = Math.Max(
dp[i, j],
a[i - 1]
+ ((i >= 2)
? dp[i - 2, j - a[i - 1]]
: 0));
}
}
}
// Return the maximum sum
return dp[n, k];
}
// Driver code
public static void Main()
{
int N = 5;
int [] arr = { 50, 10, 20, 30, 40 };
int K = 100;
// Print answer
Console.WriteLine(maxSum(arr, N, K));
}
} |
// JavaScript program to find the maximum sum that // doesn't exceed K by choosing elements function maxSum(a, n, k) {
// Initialize the DP table
let dp = new Array(n + 1);
for (let i = 0; i < n + 1; i++) {
dp[i] = new Array(k + 1).fill(0);
}
// Fill the DP table in bottom-up manner
for (let i = 1; i <= n; i++) {
for (let j = 1; j <= k; j++) {
// Don't pick the current element
dp[i][j] = dp[i - 1][j];
// Pick the current element
if (j >= a[i - 1]) {
dp[i][j] = Math.max(dp[i][j], a[i - 1] + dp[(i - 2) < 0 ? n: i-2][j - a[i - 1]]);
}
}
}
// Return the maximum sum
return dp[n][k];
} // Driver Code let N = 5; let arr = [50, 10, 20, 30, 40]; let K = 100; // Print answer console.log(maxSum(arr, N, K)); // The code is contributed by Arushi Goel. |
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*K)