Maximize array elements upto given number
Last Updated :
14 Sep, 2023
Given an array of integers, a number and a maximum value, task is to compute the maximum value that can be obtained from the array elements. Every value on the array traversing from the beginning can be either added to or subtracted from the result obtained from previous index such that at any point the result is not less than 0 and not greater than the given maximum value. For index 0 take previous result equal to given number. In case of no possible answer print -1.
Examples :
Input : arr[] = {2, 1, 7}
Number = 3
Maximum value = 7
Output : 7
The order of addition and subtraction
is: 3(given number) - 2(arr[0]) -
1(arr[1]) + 7(arr[2]).
Input : arr[] = {3, 10, 6, 4, 5}
Number = 1
Maximum value = 15
Output : 9
The order of addition and subtraction
is: 1 + 3 + 10 - 6 - 4 + 5
Prerequisite : Dynamic Programming | Recursion.
Naive Approach : Use recursion to find maximum value. At every index position there are two choices, either add current array element to value obtained so far from previous elements or subtract current array element from value obtained so far from previous elements. Start from index 0, add or subtract arr[0] from given number and recursively call for next index along with updated number. When entire array is traversed, compare the updated number with overall maximum value of number obtained so far.
Below is the implementation of above approach :
C++
#include <bits/stdc++.h>
using namespace std;
void findMaxValUtil( int arr[], int n, int num,
int maxLimit, int ind, int & ans)
{
if (ind == n) {
ans = max(ans, num);
return ;
}
if (num - arr[ind] >= 0)
{
findMaxValUtil(arr, n, num - arr[ind],
maxLimit, ind + 1, ans);
}
if (num + arr[ind] <= maxLimit)
{
findMaxValUtil(arr, n, num + arr[ind],
maxLimit, ind + 1, ans);
}
}
int findMaxVal( int arr[], int n,
int num, int maxLimit)
{
int ans = 0;
int ind = 0;
findMaxValUtil(arr, n, num, maxLimit, ind, ans);
return ans;
}
int main()
{
int num = 1;
int arr[] = { 3, 10, 6, 4, 5 };
int n = sizeof (arr) / sizeof (arr[0]);
int maxLimit = 15;
cout << findMaxVal(arr, n, num, maxLimit);
return 0;
}
|
Java
import java.io.*;
import java.lang.*;
public class GFG {
static int ans;
static void findMaxValUtil( int []arr, int n, int num,
int maxLimit, int ind)
{
if (ind == n) {
ans = Math.max(ans, num);
return ;
}
if (num - arr[ind] >= 0 )
{
findMaxValUtil(arr, n, num - arr[ind],
maxLimit, ind + 1 );
}
if (num + arr[ind] <= maxLimit)
{
findMaxValUtil(arr, n, num + arr[ind],
maxLimit, ind + 1 );
}
}
static int findMaxVal( int []arr, int n,
int num, int maxLimit)
{
int ind = 0 ;
findMaxValUtil(arr, n, num, maxLimit, ind);
return ans;
}
public static void main(String args[])
{
int num = 1 ;
int []arr = { 3 , 10 , 6 , 4 , 5 };
int n = arr.length;
int maxLimit = 15 ;
System.out.print(findMaxVal(arr, n, num,
maxLimit));
}
}
|
Python3
ans = 0 ;
def findMaxValUtil(arr, n, num, maxLimit, ind):
global ans
if (ind = = n) :
ans = max (ans, num)
return
if (num - arr[ind] > = 0 ) :
findMaxValUtil(arr, n, num - arr[ind],
maxLimit, ind + 1 )
if (num + arr[ind] < = maxLimit) :
findMaxValUtil(arr, n, num + arr[ind],
maxLimit, ind + 1 )
def findMaxVal(arr, n, num, maxLimit) :
global ans
ind = 0
findMaxValUtil(arr, n, num, maxLimit, ind)
return ans
num = 1
arr = [ 3 , 10 , 6 , 4 , 5 ]
n = len (arr)
maxLimit = 15
print (findMaxVal(arr, n, num, maxLimit))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static void findMaxValUtil( int []arr, int n, int num,
int maxLimit, int ind, ref int ans)
{
if (ind == n) {
ans = Math.Max(ans, num);
return ;
}
if (num - arr[ind] >= 0)
{
findMaxValUtil(arr, n, num - arr[ind],
maxLimit, ind + 1, ref ans);
}
if (num + arr[ind] <= maxLimit)
{
findMaxValUtil(arr, n, num + arr[ind],
maxLimit, ind + 1, ref ans);
}
}
static int findMaxVal( int []arr, int n,
int num, int maxLimit)
{
int ans = 0;
int ind = 0;
findMaxValUtil(arr, n, num, maxLimit, ind,
ref ans);
return ans;
}
public static void Main()
{
int num = 1;
int []arr = { 3, 10, 6, 4, 5 };
int n = arr.Length;
int maxLimit = 15;
Console.Write(findMaxVal(arr, n, num,
maxLimit));
}
}
|
Javascript
<script>
let ans = 0;
function findMaxValUtil(arr, n, num, maxLimit, ind)
{
if (ind == n)
{
ans = Math.max(ans, num);
return ;
}
if (num - arr[ind] >= 0)
{
findMaxValUtil(arr, n, num - arr[ind],
maxLimit, ind + 1);
}
if (num + arr[ind] <= maxLimit)
{
findMaxValUtil(arr, n, num + arr[ind],
maxLimit, ind + 1);
}
}
function findMaxVal(arr, n, num, maxLimit)
{
let ind = 0;
findMaxValUtil(arr, n, num, maxLimit, ind);
return ans;
}
let num = 1;
let arr = [ 3, 10, 6, 4, 5 ];
let n = arr.length;
let maxLimit = 15;
document.write(findMaxVal(arr, n, num,
maxLimit));
</script>
|
PHP
<?php
function findMaxValUtil( $arr , $n ,
$num , $maxLimit ,
$ind , & $ans )
{
if ( $ind == $n )
{
$ans = max( $ans , $num );
return ;
}
if ( $num - $arr [ $ind ] >= 0)
{
findMaxValUtil( $arr , $n ,
$num - $arr [ $ind ],
$maxLimit , $ind + 1,
$ans );
}
if ( $num + $arr [ $ind ] <= $maxLimit )
{
findMaxValUtil( $arr , $n ,
$num + $arr [ $ind ],
$maxLimit , $ind + 1,
$ans );
}
}
function findMaxVal( $arr , $n ,
$num , $maxLimit )
{
$ans = 0;
$ind = 0;
findMaxValUtil( $arr , $n , $num ,
$maxLimit , $ind , $ans );
return $ans ;
}
$num = 1;
$arr = array (3, 10, 6, 4, 5);
$n = count ( $arr );
$maxLimit = 15;
echo (findMaxVal( $arr , $n , $num , $maxLimit ));
?>
|
Time Complexity : O(2^n).
Note : For small values of n <= 20, this solution will work. But as array size increases, this will not be an optimal solution.
An efficient solution is to use Dynamic Programming. Observe that the value at every step is constrained between 0 and maxLimit and hence, the required maximum value will also lie in this range. At every index position, after arr[i] is added to or subtracted from result, the new value of result will also lie in this range. Lets try to build the solution backwards. Suppose the required maximum possible value is x, where 0 ≤ x ≤ maxLimit. This value x is obtained by either adding or subtracting arr[n-1] to/from the value obtained until index position n-2. The same reason can be given for value obtained at index position n-2 that it depends on value at index position n-3 and so on. The resulting recurrence relation can be given as :
Check can x be obtained from arr[0..n-1]:
Check can x - arr[n-1] be obtained from arr[0..n-2]
|| Check can x + arr[n-1] be obtained from arr[0..n-2]
A boolean DP table can be created in which dp[i][j] is 1 if value j can be obtained using arr[0..i] and 0 if not. For each index position, start from j = 0 and move to value maxLimit, and set dp[i][j] either 0 or 1 as described above. Find the maximum possible value that can be obtained at index position n-1 by finding maximum j when i = n-1 and dp[n-1][j] = 1.
Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
int findMaxVal( int arr[], int n,
int num, int maxLimit)
{
int ind;
int val;
int dp[n][maxLimit+1];
for (ind = 0; ind < n; ind++)
{
for (val = 0; val <= maxLimit; val++)
{
if (ind == 0)
{
if (num - arr[ind] == val ||
num + arr[ind] == val)
{
dp[ind][val] = 1;
}
else
{
dp[ind][val] = 0;
}
}
else
{
if (val - arr[ind] >= 0 &&
val + arr[ind] <= maxLimit)
{
dp[ind][val] = dp[ind-1][val-arr[ind]] ||
dp[ind-1][val+arr[ind]];
}
else if (val - arr[ind] >= 0)
{
dp[ind][val] = dp[ind-1][val-arr[ind]];
}
else if (val + arr[ind] <= maxLimit)
{
dp[ind][val] = dp[ind-1][val+arr[ind]];
}
else
{
dp[ind][val] = 0;
}
}
}
}
for (val = maxLimit; val >= 0; val--)
{
if (dp[n-1][val])
{
return val;
}
}
return -1;
}
int main()
{
int num = 1;
int arr[] = {3, 10, 6, 4, 5};
int n = sizeof (arr) / sizeof (arr[0]);
int maxLimit = 15;
cout << findMaxVal(arr, n, num, maxLimit);
return 0;
}
|
Java
import java.io.*;
class GFG
{
static int findMaxVal( int []arr, int n,
int num, int maxLimit)
{
int ind;
int val;
int [][]dp = new int [n][maxLimit + 1 ];
for (ind = 0 ; ind < n; ind++)
{
for (val = 0 ; val <= maxLimit; val++)
{
if (ind == 0 )
{
if (num - arr[ind] == val ||
num + arr[ind] == val)
{
dp[ind][val] = 1 ;
}
else
{
dp[ind][val] = 0 ;
}
}
else
{
if (val - arr[ind] >= 0 &&
val + arr[ind] <= maxLimit)
{
if (dp[ind - 1 ][val - arr[ind]] == 1
|| dp[ind - 1 ][val + arr[ind]] == 1 )
dp[ind][val] = 1 ;
}
else if (val - arr[ind] >= 0 )
{
dp[ind][val] = dp[ind - 1 ][val -
arr[ind]];
}
else if (val + arr[ind] <= maxLimit)
{
dp[ind][val] = dp[ind - 1 ][val +
arr[ind]];
}
else
{
dp[ind][val] = 0 ;
}
}
}
}
for (val = maxLimit; val >= 0 ; val--)
{
if (dp[n - 1 ][val] == 1 )
{
return val;
}
}
return - 1 ;
}
public static void main(String args[])
{
int num = 1 ;
int []arr = new int []{ 3 , 10 , 6 , 4 , 5 };
int n = arr.length;
int maxLimit = 15 ;
System.out.print(findMaxVal(arr, n,
num, maxLimit));
}
}
|
Python3
def findMaxVal(arr, n, num, maxLimit):
ind = - 1 ;
val = - 1 ;
dp = [[ 0 for i in range (maxLimit + 1 )] for j in range (n)];
for ind in range (n):
for val in range (maxLimit + 1 ):
if (ind = = 0 ):
if (num - arr[ind] = = val or num + arr[ind] = = val):
dp[ind][val] = 1 ;
else :
dp[ind][val] = 0 ;
else :
if (val - arr[ind] > = 0 and val + arr[ind] < = maxLimit):
if (dp[ind - 1 ][val - arr[ind]] = = 1 or
dp[ind - 1 ][val + arr[ind]] = = 1 ):
dp[ind][val] = 1 ;
elif (val - arr[ind] > = 0 ):
dp[ind][val] = dp[ind - 1 ][val - arr[ind]];
elif (val + arr[ind] < = maxLimit):
dp[ind][val] = dp[ind - 1 ][val + arr[ind]];
else :
dp[ind][val] = 0 ;
for val in range (maxLimit, - 1 , - 1 ):
if (dp[n - 1 ][val] = = 1 ):
return val;
return - 1 ;
if __name__ = = '__main__' :
num = 1 ;
arr = [ 3 , 10 , 6 , 4 , 5 ];
n = len (arr);
maxLimit = 15 ;
print (findMaxVal(arr, n, num, maxLimit));
|
C#
using System;
class GFG {
static int findMaxVal( int []arr, int n,
int num, int maxLimit)
{
int ind;
int val;
int [,]dp = new int [n,maxLimit+1];
for (ind = 0; ind < n; ind++)
{
for (val = 0; val <= maxLimit; val++)
{
if (ind == 0)
{
if (num - arr[ind] == val ||
num + arr[ind] == val)
{
dp[ind,val] = 1;
}
else
{
dp[ind,val] = 0;
}
}
else
{
if (val - arr[ind] >= 0 &&
val + arr[ind] <= maxLimit)
{
if (dp[ind-1,val-arr[ind]] == 1
|| dp[ind-1,val+arr[ind]] == 1)
dp[ind,val] = 1;
}
else if (val - arr[ind] >= 0)
{
dp[ind,val] = dp[ind-1,val-arr[ind]];
}
else if (val + arr[ind] <= maxLimit)
{
dp[ind,val] = dp[ind-1,val+arr[ind]];
}
else
{
dp[ind,val] = 0;
}
}
}
}
for (val = maxLimit; val >= 0; val--)
{
if (dp[n-1,val] == 1)
{
return val;
}
}
return -1;
}
static void Main()
{
int num = 1;
int []arr = new int []{3, 10, 6, 4, 5};
int n = arr.Length;
int maxLimit = 15;
Console.Write(
findMaxVal(arr, n, num, maxLimit));
}
}
|
Javascript
<script>
function findMaxVal(arr, n, num, maxLimit)
{
var ind;
var val;
var dp = Array.from( Array(n), () => Array(maxLimit+1));
for (ind = 0; ind < n; ind++)
{
for (val = 0; val <= maxLimit; val++)
{
if (ind == 0)
{
if (num - arr[ind] == val ||
num + arr[ind] == val)
{
dp[ind][val] = 1;
}
else
{
dp[ind][val] = 0;
}
}
else
{
if (val - arr[ind] >= 0 &&
val + arr[ind] <= maxLimit)
{
dp[ind][val] = dp[ind-1][val-arr[ind]] ||
dp[ind-1][val+arr[ind]];
}
else if (val - arr[ind] >= 0)
{
dp[ind][val] = dp[ind-1][val-arr[ind]];
}
else if (val + arr[ind] <= maxLimit)
{
dp[ind][val] = dp[ind-1][val+arr[ind]];
}
else
{
dp[ind][val] = 0;
}
}
}
}
for (val = maxLimit; val >= 0; val--)
{
if (dp[n-1][val])
{
return val;
}
}
return -1;
}
var num = 1;
var arr = [3, 10, 6, 4, 5];
var n = arr.length;
var maxLimit = 15;
document.write( findMaxVal(arr, n, num, maxLimit));
</script>
|
PHP
<?php
function findMaxVal( $arr , $n , $num ,
$maxLimit )
{
$ind ;
$val ;
$dp [ $n ][ $maxLimit + 1] = array ();
for ( $ind = 0; $ind < $n ; $ind ++)
{
for ( $val = 0;
$val <= $maxLimit ; $val ++)
{
if ( $ind == 0)
{
if ( $num - $arr [ $ind ] == $val ||
$num + $arr [ $ind ] == $val )
{
$dp [ $ind ][ $val ] = 1;
}
else
{
$dp [ $ind ][ $val ] = 0;
}
}
else
{
if ( $val - $arr [ $ind ] >= 0 &&
$val + $arr [ $ind ] <= $maxLimit )
{
$dp [ $ind ][ $val ] = $dp [ $ind - 1][ $val - $arr [ $ind ]] ||
$dp [ $ind - 1][ $val + $arr [ $ind ]];
}
else if ( $val - $arr [ $ind ] >= 0)
{
$dp [ $ind ][ $val ] = $dp [ $ind - 1][ $val - $arr [ $ind ]];
}
else if ( $val + $arr [ $ind ] <= $maxLimit )
{
$dp [ $ind ][ $val ] = $dp [ $ind - 1][ $val + $arr [ $ind ]];
}
else
{
$dp [ $ind ][ $val ] = 0;
}
}
}
}
for ( $val = $maxLimit ; $val >= 0; $val --)
{
if ( $dp [ $n - 1][ $val ])
{
return $val ;
}
}
return -1;
}
$num = 1;
$arr = array (3, 10, 6, 4, 5);
$n = sizeof( $arr );
$maxLimit = 15;
echo findMaxVal( $arr , $n , $num , $maxLimit );
?>
|
Complexity Analysis:
- Time Complexity : O(n*maxLimit), where n is the size of array and maxLimit is the given max value.
- Auxiliary Space : O(n*maxLimit), n is the size of array and maxLimit is the given max value.
Optimization : The space required can be reduced to O(2*maxLimit). Note that at every index position, we are only using values from previous row. So we can create a table with two rows, in which one of the rows store result for previous iteration and other for the current iteration.
Efficient approach : Space optimization
In previous approach the current value dp[i][j] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.
Implementation steps:
- Create a 1D vector dp of size maxLimit+1.
- Set a base case by initializing the values of dp.
- Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
- Now Create a temporary 1d vector temp used to store the current values from previous computations.
- After every iteration assign the value of temp to dp for further iteration.
- Initialize a variable val and find the maximum value that is obtained at index n-1.
- At last return and print the final answer stored in val.
Implementation:
C++
#include <iostream>
#include <vector>
using namespace std;
int findMaxVal( int arr[], int n, int num, int maxLimit)
{
int ind;
int val;
vector< int > dp(maxLimit + 1, 0);
for (ind = 0; ind < n; ind++)
{
vector< int > temp(maxLimit + 1, 0);
for (val = 0; val <= maxLimit; val++)
{
if (ind == 0)
{
if (num - arr[ind] == val || num + arr[ind] == val)
{
temp[val] = 1;
}
}
else
{
if (val - arr[ind] >= 0 && val + arr[ind] <= maxLimit)
{
temp[val] = dp[val - arr[ind]] || dp[val + arr[ind]];
}
else if (val - arr[ind] >= 0)
{
temp[val] = dp[val - arr[ind]];
}
else if (val + arr[ind] <= maxLimit)
{
temp[val] = dp[val + arr[ind]];
}
}
}
dp = temp;
}
for (val = maxLimit; val >= 0; val--)
{
if (dp[val])
{
return val;
}
}
return -1;
}
int main()
{
int num = 1;
int arr[] = {3, 10, 6, 4, 5};
int n = sizeof (arr) / sizeof (arr[0]);
int maxLimit = 15;
cout << findMaxVal(arr, n, num, maxLimit);
return 0;
}
|
Java
import java.util.*;
public class GFG {
public static int findMaxVal( int [] arr, int n, int num,
int maxLimit)
{
int ind;
int val;
List<Boolean> dp = new ArrayList<>(
Collections.nCopies(maxLimit + 1 , false ));
for (ind = 0 ; ind < n; ind++) {
List<Boolean> temp = new ArrayList<>(
Collections.nCopies(maxLimit + 1 , false ));
for (val = 0 ; val <= maxLimit; val++) {
if (ind == 0 ) {
if (num - arr[ind] == val
|| num + arr[ind] == val) {
temp.set(val, true );
}
}
else {
if (val - arr[ind] >= 0
&& val + arr[ind] <= maxLimit) {
temp.set(
val,
dp.get(val - arr[ind])
|| dp.get(val + arr[ind]));
}
else if (val - arr[ind] >= 0 ) {
temp.set(val,
dp.get(val - arr[ind]));
}
else if (val + arr[ind] <= maxLimit) {
temp.set(val,
dp.get(val + arr[ind]));
}
}
}
dp = temp;
}
for (val = maxLimit; val >= 0 ; val--) {
if (dp.get(val)) {
return val;
}
}
return - 1 ;
}
public static void main(String[] args)
{
int num = 1 ;
int [] arr = { 3 , 10 , 6 , 4 , 5 };
int n = arr.length;
int maxLimit = 15 ;
System.out.println(
findMaxVal(arr, n, num, maxLimit));
}
}
|
Python
def findMaxVal(arr, n, num, maxLimit):
dp = [ 0 ] * (maxLimit + 1 )
for ind in range (n):
temp = [ 0 ] * (maxLimit + 1 )
for val in range (maxLimit + 1 ):
if ind = = 0 :
if num - arr[ind] = = val or num + arr[ind] = = val:
temp[val] = 1
else :
if 0 < = val - arr[ind] < = maxLimit and 0 < = val + arr[ind] < = maxLimit:
temp[val] = dp[val - arr[ind]] or dp[val + arr[ind]]
elif 0 < = val - arr[ind] < = maxLimit:
temp[val] = dp[val - arr[ind]]
elif 0 < = val + arr[ind] < = maxLimit:
temp[val] = dp[val + arr[ind]]
dp = temp
for val in range (maxLimit, - 1 , - 1 ):
if dp[val]:
return val
return - 1
if __name__ = = "__main__" :
num = 1
arr = [ 3 , 10 , 6 , 4 , 5 ]
n = len (arr)
maxLimit = 15
print (findMaxVal(arr, n, num, maxLimit))
|
C#
using System;
using System.Collections.Generic;
class GFG {
static int FindMaxVal( int [] arr, int n, int num,
int maxLimit)
{
int ind;
int val;
List< int > dp = new List< int >(maxLimit + 1);
dp.AddRange( new int [maxLimit + 1]);
for (ind = 0; ind < n; ind++) {
List< int > temp = new List< int >(maxLimit + 1);
temp.AddRange( new int [maxLimit + 1]);
for (val = 0; val <= maxLimit; val++) {
if (ind == 0) {
if (num - arr[ind] == val
|| num + arr[ind] == val) {
temp[val] = 1;
}
}
else {
if (val - arr[ind] >= 0
&& val + arr[ind] <= maxLimit) {
temp[val] = dp[val - arr[ind]]
| dp[val + arr[ind]];
}
else if (val - arr[ind] >= 0) {
temp[val] = dp[val - arr[ind]];
}
else if (val + arr[ind] <= maxLimit) {
temp[val] = dp[val + arr[ind]];
}
}
}
dp = temp;
}
for (val = maxLimit; val >= 0; val--) {
if (dp[val] == 1) {
return val;
}
}
return -1;
}
static void Main()
{
int num = 1;
int [] arr = { 3, 10, 6, 4, 5 };
int n = arr.Length;
int maxLimit = 15;
Console.WriteLine(
FindMaxVal(arr, n, num, maxLimit));
}
}
|
Javascript
function findMaxVal(arr, n, num, maxLimit) {
let ind;
let val;
let dp = new Array(maxLimit + 1).fill(0);
for (ind = 0; ind < n; ind++) {
let temp = new Array(maxLimit + 1).fill(0);
for (val = 0; val <= maxLimit; val++) {
if (ind === 0) {
if (num - arr[ind] === val || num + arr[ind] === val) {
temp[val] = 1;
}
}
else {
if (val - arr[ind] >= 0 && val + arr[ind] <= maxLimit)
{
temp[val] = dp[val - arr[ind]] || dp[val + arr[ind]];
}
else if (val - arr[ind] >= 0)
{
temp[val] = dp[val - arr[ind]];
}
else if (val + arr[ind] <= maxLimit)
{
temp[val] = dp[val + arr[ind]];
}
}
}
dp = temp;
}
for (val = maxLimit; val >= 0; val--) {
if (dp[val]) {
return val;
}
}
return -1;
}
const num = 1;
const arr = [3, 10, 6, 4, 5];
const n = arr.length;
const maxLimit = 15;
console.log(GFG(arr, n, num, maxLimit));
|
Time Complexity : O(n*maxLimit), where n is the size of array and maxLimit is the given max value.
Auxiliary Space : O(maxLimit)
Optimization :
Optimized space complexity by using 1d vector instead of 2d matrix.
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...