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.

Example :

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 :**

[sourcecode language=”CPP”]

// CPP code to find maximum

// value of number obtained by

// using array elements recursively.

#include <bits/stdc++.h>

using namespace std;

// Utility function to find maximum possible value

void findMaxValUtil(int arr[], int n, int num,

int maxLimit, int ind, int& ans)

{

// If entire array is traversed, then compare

// current value in num to overall maximum

// obtained so far.

if (ind == n) {

ans = max(ans, num);

return;

}

// Case 1: Subtract current element from value so

// far if result is greater than or equal to zero.

if (num – arr[ind] >= 0)

{

findMaxValUtil(arr, n, num – arr[ind],

maxLimit, ind + 1, ans);

}

// Case 2 : Add current element to value so far

// if result is less than or equal to maxLimit.

if (num + arr[ind] <= maxLimit)

{

findMaxValUtil(arr, n, num + arr[ind],

maxLimit, ind + 1, ans);

}

}

// Function to find maximum possible

// value that can be obtained using

// array elements and given number.

int findMaxVal(int arr[], int n,

int num, int maxLimit)

{

// variable to store maximum value

// that can be obtained.

int ans = 0;

// variable to store current index position.

int ind = 0;

// call to utility function to find maximum

// possible value that can be obtained.

findMaxValUtil(arr, n, num, maxLimit, ind, ans);

return ans;

}

// Driver code

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;

}

[/sourcecode]

**Output:**

9

**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.

[sourcecode language=”CPP”]

// CPP program to find maximum value of

// number obtained by using array

// elements by using dynamic programming.

#include <bits/stdc++.h>

using namespace std;

// Function to find maximum possible

// value of number that can be

// obtained using array elements.

int findMaxVal(int arr[], int n,

int num, int maxLimit)

{

// Variable to represent current index.

int ind;

// Variable to show value between

// 0 and maxLimit.

int val;

// Table to store whether a value can

// be obtained or not upto a certain index.

// 1. dp[i][j] = 1 if value j can be

// obtained upto index i.

// 2. dp[i][j] = 0 if value j cannot be

// obtained upto index i.

int dp[n][maxLimit+1];

for(ind = 0; ind < n; ind++)

{

for(val = 0; val <= maxLimit; val++)

{

// Check for index 0 if given value

// val can be obtained by either adding

// to or subtracting arr[0] from num.

if(ind == 0)

{

if(num – arr[ind] == val ||

num + arr[ind] == val)

{

dp[ind][val] = 1;

}

else

{

dp[ind][val] = 0;

}

}

else

{

// 1. If arr[ind] is added to

// obtain given val then val-

// arr[ind] should be obtainable

// from index ind-1.

// 2. If arr[ind] is subtracted to

// obtain given val then val+arr[ind]

// should be obtainable from index ind-1.

// Check for both the conditions.

if(val – arr[ind] >= 0 &&

val + arr[ind] <= maxLimit)

{

// If either of one condition is true,

// then val is obtainable at index ind.

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;

}

}

}

}

// Find maximum value that is obtained

// at index n-1.

for(val = maxLimit; val >= 0; val–)

{

if(dp[n-1][val])

{

return val;

}

}

// If no solution exists return -1.

return -1;

}

// Driver Code

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;

}

[/sourcecode]

**Output:**

9

**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.

## Recommended Posts:

- Maximize the sum of X+Y elements by picking X and Y elements from 1st and 2nd array
- Maximize elements using another array
- Count number of elements between two given elements in array
- Maximum number of contiguous array elements with same number of set bits
- Maximize value of (arr[i] - i) - (arr[j] - j) in an array
- Maximize value of (a[i]+i)*(a[j]+j) in an array
- Reverse an array upto a given position
- Maximize array sum after K negations | Set 1
- Given an array and three numbers, maximize (x * a[i]) + (y * a[j]) + (z * a[k])
- Maximize the median of an array
- Maximize the bitwise OR of an array
- Maximize array sum after K negations | Set 2
- Rearrange an array to maximize i*arr[i]
- Maximize sum of consecutive differences in a circular array
- Remove array end element to maximize the sum of product

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.