Maximum possible sum of non-adjacent array elements not exceeding K
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++
#include <bits/stdc++.h>
using namespace std;
int maxSum( int a[],
int n, int k)
{
if (n <= 0)
return 0;
int option = maxSum(a,
n - 1, k);
if (k >= a[n - 1])
option = max(option,
a[n - 1] +
maxSum(a, n - 2,
k - a[n - 1]));
return option;
}
int main()
{
int arr[] = {50, 10,
20, 30, 40};
int N = sizeof (arr) /
sizeof (arr[0]);
int K = 100;
cout << (maxSum(arr,
N, K));
}
|
Java
import java.io.*;
class GFG {
public static int maxSum(
int a[], int n, int k)
{
if (n <= 0 )
return 0 ;
int option = maxSum(a, n - 1 , k);
if (k >= a[n - 1 ])
option = Math.max(
option,
a[n - 1 ]
+ maxSum(a, n - 2 ,
k - a[n - 1 ]));
return option;
}
public static void main(String[] args)
{
int arr[] = { 50 , 10 , 20 , 30 , 40 };
int N = arr.length;
int K = 100 ;
System.out.println(maxSum(arr, N, K));
}
}
|
Python3
def maxSum(a, n, k):
if (n < = 0 ):
return 0
option = maxSum(a, n - 1 , k)
if (k > = a[n - 1 ]):
option = max (option, a[n - 1 ] +
maxSum(a, n - 2 , k - a[n - 1 ]))
return option
if __name__ = = '__main__' :
arr = [ 50 , 10 , 20 , 30 , 40 ]
N = len (arr)
K = 100
print (maxSum(arr, N, K))
|
C#
using System;
class GFG{
public static int maxSum( int []a,
int n, int k)
{
if (n <= 0)
return 0;
int option = maxSum(a, n - 1, k);
if (k >= a[n - 1])
option = Math.Max(option, a[n - 1] +
maxSum(a, n - 2,
k - a[n - 1]));
return option;
}
public static void Main(String[] args)
{
int []arr = {50, 10, 20, 30, 40};
int N = arr.Length;
int K = 100;
Console.WriteLine(maxSum(arr, N, K));
}
}
|
Javascript
<script>
function maxSum(a, n, k)
{
if (n <= 0)
return 0;
let option = maxSum(a, n - 1, k);
if (k >= a[n - 1])
option = Math.max(option, a[n - 1] +
maxSum(a, n - 2, k - a[n - 1]));
return option;
}
let arr = [ 50, 10, 20, 30, 40 ];
let N = arr.length;
let K = 100;
document.write(maxSum(arr, N, K));
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
int dp[1005][1005];
int maxSum( int * a, int n, int k)
{
if (n <= 0)
return 0;
if (dp[n][k] != -1)
return dp[n][k];
int option = maxSum(a, n - 1, k);
if (k >= a[n - 1])
option = max(option,
a[n - 1] +
maxSum(a, n - 2,
k - a[n - 1]));
return dp[n][k] = option;
}
int main()
{
int N = 5;
int arr[] = { 50, 10, 20, 30, 40 };
int K = 100;
memset (dp, -1, sizeof (dp));
cout << maxSum(arr, N, K) << endl;
}
|
Java
import java.util.*;
class GFG {
public static int maxSum( int a[], int n,
int k, int [][] dp)
{
if (n <= 0 )
return 0 ;
if (dp[n][k] != - 1 )
return dp[n][k];
int option = maxSum(a, n - 1 ,
k, dp);
if (k >= a[n - 1 ])
option = Math.max(
option,
a[n - 1 ]
+ maxSum(a, n - 2 ,
k - a[n - 1 ],
dp));
return dp[n][k] = option;
}
public static void main(String[] args)
{
int arr[] = { 50 , 10 , 20 , 30 , 40 };
int N = arr.length;
int K = 100 ;
int dp[][] = new int [N + 1 ][K + 1 ];
for ( int i[] : dp) {
Arrays.fill(i, - 1 );
}
System.out.println(maxSum(arr, N, K, dp));
}
}
|
Python3
def maxSum(a, n, k, dp):
if (n < = 0 ):
return 0 ;
if (dp[n][k] ! = - 1 ):
return dp[n][k];
option = maxSum(a, n - 1 ,
k, dp);
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 dp[n][k];
if __name__ = = '__main__' :
arr = [ 50 , 10 , 20 ,
30 , 40 ];
N = len (arr);
K = 100 ;
dp = [[ - 1 for i in range (K + 1 )]
for j in range (N + 1 )]
print (maxSum(arr, N,
K, dp));
|
C#
using System;
class GFG{
public static int maxSum( int []a, int n,
int k, int [,] dp)
{
if (n <= 0)
return 0;
if (dp[n, k] != -1)
return dp[n, k];
int option = maxSum(a, n - 1,
k, dp);
if (k >= a[n - 1])
option = Math.Max(option, a[n - 1] +
maxSum(a, n - 2,
k - a[n - 1],
dp));
return dp[n, k] = option;
}
public static void Main(String[] args)
{
int []arr = {50, 10, 20, 30, 40};
int N = arr.Length;
int K = 100;
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;
}
Console.WriteLine(maxSum(arr, N,
K, dp));
}
}
|
Javascript
<script>
function maxSum(a, n, k, dp)
{
if (n <= 0)
return 0;
if (dp[n][k] != -1)
return dp[n][k];
let option = maxSum(a, n - 1,
k, dp);
if (k >= a[n - 1])
option = Math.max(
option,
a[n - 1]
+ maxSum(a, n - 2,
k - a[n - 1],
dp));
return dp[n][k] = option;
}
let arr = [ 50, 10, 20, 30, 40 ];
let N = arr.length;
let K = 100;
let dp = new Array(N + 1);
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;
}
}
document.write(maxSum(arr, N, K, dp));
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
int maxSum( int * a, int n, int k)
{
int dp[n + 1][k + 1];
memset (dp, 0, sizeof (dp));
for ( int i = 1; i <= n; i++) {
for ( int j = 1; j <= k; j++) {
dp[i][j] = dp[i - 1][j];
if (j >= a[i - 1]) {
dp[i][j] = max(
dp[i][j],
a[i - 1] + dp[i - 2][j - a[i - 1]]);
}
}
}
return dp[n][k];
}
int main()
{
int N = 5;
int arr[] = { 50, 10, 20, 30, 40 };
int K = 100;
cout << maxSum(arr, N, K) << endl;
return 0;
}
|
Java
import java.util.*;
public class Main {
public static int maxSum( int [] a, int n, int k) {
int [][] dp = new int [n + 1 ][k + 1 ];
for ( int [] row : dp) {
Arrays.fill(row, 0 );
}
for ( int i = 1 ; i <= n; i++) {
for ( int j = 1 ; j <= k; j++) {
dp[i][j] = dp[i - 1 ][j];
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 dp[n][k];
}
public static void main(String[] args) {
int N = 5 ;
int [] arr = { 50 , 10 , 20 , 30 , 40 };
int K = 100 ;
System.out.println(maxSum(arr, N, K));
}
}
|
Python3
def maxSum(a, n, k):
dp = [[ 0 for i in range (k + 1 )] for j in range (n + 1 )]
for i in range ( 1 , n + 1 ):
for j in range ( 1 , k + 1 ):
dp[i][j] = dp[i - 1 ][j]
if j > = a[i - 1 ]:
dp[i][j] = max (dp[i][j], a[i - 1 ] + dp[i - 2 ][j - a[i - 1 ]])
return dp[n][k]
if __name__ = = "__main__" :
N = 5
arr = [ 50 , 10 , 20 , 30 , 40 ]
K = 100
print (maxSum(arr, N, K))
|
C#
using System;
public class GFG {
public static int maxSum( int [] a, int n, int k)
{
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;
}
}
for ( int i = 1; i <= n; i++) {
for ( int j = 1; j <= k; j++) {
dp[i, j] = dp[i - 1, j];
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 dp[n, k];
}
public static void Main()
{
int N = 5;
int [] arr = { 50, 10, 20, 30, 40 };
int K = 100;
Console.WriteLine(maxSum(arr, N, K));
}
}
|
Javascript
function maxSum(a, n, k) {
let dp = new Array(n + 1);
for (let i = 0; i < n + 1; i++) {
dp[i] = new Array(k + 1).fill(0);
}
for (let i = 1; i <= n; i++) {
for (let j = 1; j <= k; j++) {
dp[i][j] = dp[i - 1][j];
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 dp[n][k];
}
let N = 5;
let arr = [50, 10, 20, 30, 40];
let K = 100;
console.log(maxSum(arr, N, K));
|
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)
Last Updated :
27 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...