Open In App

Maximize array elements upto given number

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 : 




// 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;
}




// Java code to find maximum
// value of number obtained by
// using array elements recursively.
import java.io.*;
import java.lang.*;
  
public class GFG {
 
    // variable to store maximum value
    // that can be obtained.
    static int ans;
     
    // Utility function to find maximum
    // possible value
    static void findMaxValUtil(int []arr, int n, int num,
                              int maxLimit, int ind)
    {
          
        // If entire array is traversed, then compare
        // current value in num to overall maximum
        // obtained so far.
        if (ind == n) {
            ans = Math.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);
        }
      
        // 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);
        }
    }
      
    // Function to find maximum possible
    // value that can be obtained using
    // array elements and given number.
    static int findMaxVal(int []arr, int n,
                             int num, int maxLimit)
    {
          
         
      
        // 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);
      
        return ans;
    }
      
    // Driver code
    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));
    }
}
 
// This code is contributed by Manish Shaw
// (manishshaw1)




# Python3 code to find maximum
# value of number obtained by
# using array elements recursively.
 
# Utility def to find
# maximum possible value
 
# variable to store maximum value
# that can be obtained.
ans = 0;
def findMaxValUtil(arr, n, num, maxLimit, ind):
    global 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)
 
    # 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)
 
# def to find maximum possible
# value that can be obtained using
# array elements and given number.
def findMaxVal(arr, n, num, maxLimit) :
    global ans
    # variable to store
    # current index position.
    ind = 0
 
    # call to utility def to
    # find maximum possible value
    # that can be obtained.
    findMaxValUtil(arr, n, num, maxLimit, ind)
    return ans
 
 
# Driver code
num = 1
arr = [3, 10, 6, 4, 5]
n = len(arr)
maxLimit = 15
 
print (findMaxVal(arr, n, num, maxLimit))
 
# This code is contributed by Manish Shaw
# (manishshaw1)




// C# code to find maximum
// value of number obtained by
// using array elements recursively.
using System;
using System.Collections.Generic;
 
class GFG {
     
    // Utility function to find maximum
    // possible value
    static void findMaxValUtil(int []arr, int n, int num,
                      int maxLimit, int ind, ref int ans)
    {
         
        // If entire array is traversed, then compare
        // current value in num to overall maximum
        // obtained so far.
        if (ind == n) {
            ans = Math.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, ref 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, ref ans);
        }
    }
     
    // Function to find maximum possible
    // value that can be obtained using
    // array elements and given number.
    static 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,
                                           ref ans);
     
        return ans;
    }
     
    // Driver code
    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));
    }
}
 
// This code is contributed by Manish Shaw
// (manishshaw1)




<script>
 
// Javascript code to find maximum
// value of number obtained by
// using array elements recursively.
 
// variable to store maximum value
// that can be obtained.
let ans = 0;
  
// Utility function to find maximum
// possible value
function findMaxValUtil(arr, n, num, maxLimit, ind)
{
     
    // If entire array is traversed, then
    // compare current value in num to
    // overall maximum obtained so far.
    if (ind == n)
    {
        ans = Math.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);
    }
   
    // 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);
    }
}
   
// Function to find maximum possible
// value that can be obtained using
// array elements and given number.
function findMaxVal(arr, n, num, maxLimit)
{
     
    // Variable to store current index position.
    let ind = 0;
   
    // Call to utility function to find maximum
    // possible value that can be obtained.
    findMaxValUtil(arr, n, num, maxLimit, ind);
   
    return ans;
}
 
// Driver code
let num = 1;
let arr = [ 3, 10, 6, 4, 5 ];
let n = arr.length;
let maxLimit = 15;
 
document.write(findMaxVal(arr, n, num,
                          maxLimit));
                             
// This code is contributed by mukesh07  
 
</script>




<?php
// PHP code to find maximum
// value of number obtained by
// using array elements recursively.
 
// Utility function to find
// maximum possible value
function findMaxValUtil($arr, $n,
                        $num, $maxLimit,
                        $ind, &$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.
function findMaxVal($arr, $n,
                    $num, $maxLimit)
{
    // variable to store maximum value
    // that can be obtained.
    $ans = 0;
 
    // variable to store
    // current index position.
    $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
$num = 1;
$arr = array(3, 10, 6, 4, 5);
$n = count($arr);
$maxLimit = 15;
 
echo (findMaxVal($arr, $n, $num, $maxLimit));
 
//This code is contributed by Manish Shaw
//(manishshaw1)
?>

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. 

Implementation:




// C++ 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;
}




// Java program to find maximum
// value of number obtained by
// using array elements by using
// dynamic programming.
import java.io.*;
 
class GFG
{
     
    // Function to find maximum
    // possible value of number
    // that can be obtained
    // using array elements.
    static 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 = new int[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.
                        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;
                    }
                }
            }
        }
         
        // Find maximum value that
        // is obtained at index n-1.
        for(val = maxLimit; val >= 0; val--)
        {
            if(dp[n - 1][val] == 1)
            {
                return val;
            }
        }
         
        // If no solution
        // exists return -1.
        return -1;
    }
     
    // Driver Code
    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));
    }
}
 
// This code is contributed
// by Manish Shaw(manishshaw1)




# Python3 program to find maximum
# value of number obtained by
# using array elements by using
# dynamic programming.
 
 
# Function to find maximum
# possible value of number
# that can be obtained
# using array elements.
def findMaxVal(arr, n, num, maxLimit):
 
    # Variable to represent
    # current index.
    ind = -1;
 
    # Variable to show value
    # between 0 and maxLimit.
    val = -1;
 
    # 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.
    dp = [[0 for i in range(maxLimit + 1)] for j in range(n)];
 
    for ind in range(n):
        for val in range(maxLimit + 1):
 
            # 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 or 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 and val + arr[ind] <= maxLimit):
 
                    # If either of one condition
                    # is True, then val is
                    # obtainable at index ind.
                    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;
 
    # Find maximum value that
    # is obtained at index n-1.
    for val in range(maxLimit, -1, -1):
        if (dp[n - 1][val] == 1):
            return val;
 
    # If no solution
    # exists return -1.
    return -1;
 
# Driver Code
if __name__ == '__main__':
    num = 1;
    arr = [3, 10, 6, 4, 5];
    n = len(arr);
    maxLimit = 15;
 
    print(findMaxVal(arr, n, num, maxLimit));
 
# This code is contributed by 29AjayKumar




// C# program to find maximum value of
// number obtained by using array
// elements by using dynamic programming.
using System;
 
class GFG {
     
    // Function to find maximum possible
    // value of number that can be
    // obtained using array elements.
    static 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 = new int[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.
                        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;
                    }
                }
            }
        }
         
        // Find maximum value that is obtained
        // at index n-1.
        for(val = maxLimit; val >= 0; val--)
        {
            if(dp[n-1,val] == 1)
            {
                return val;
            }
        }
         
        // If no solution exists return -1.
        return -1;
    }
     
    // Driver Code
    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));
    }
}
 
// This code is contributed by Manish Shaw
// (manishshaw1)




<script>
 
// Javascript program to find maximum value of
// number obtained by using array
// elements by using dynamic programming.
  
// Function to find maximum possible
// value of number that can be
// obtained using array elements.
function findMaxVal(arr, n, num, maxLimit)
{
    // Variable to represent current index.
    var ind;
      
    // Variable to show value between
    //  0 and maxLimit.
    var 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.
    var dp = Array.from( Array(n), () => Array(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
var num = 1;
var arr = [3, 10, 6, 4, 5];
var n = arr.length;
var maxLimit = 15;
   
document.write( findMaxVal(arr, n, num, maxLimit));
 
// This code is contributed by rutvik_56.
</script>




<?php
// PHP program to find maximum value of
// number obtained by using array
// elements by using dynamic programming.
 
// Function to find maximum possible
// value of number that can be
// obtained using array elements.
function findMaxVal($arr, $n, $num,
                         $maxLimit)
{
    // Variable to represent
    // current index.
    $ind;
     
    // Variable to show value between
    // 0 and maxLimit.
    $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.
    $dp[$n][$maxLimit + 1] = array();
     
    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
$num = 1;
$arr = array(3, 10, 6, 4, 5);
$n = sizeof($arr);
$maxLimit = 15;
     
echo findMaxVal($arr, $n, $num, $maxLimit);
 
// This code is contributed by ajit.
?>

Output
9









Complexity Analysis:

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:

Implementation: 




#include <iostream>
#include <vector>
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;
 
    // Vector to store whether a value can
    // be obtained or not upto a certain index.
    vector<int> dp(maxLimit + 1, 0);
 
    for (ind = 0; ind < n; ind++)
    {
        vector<int> temp(maxLimit + 1, 0);
        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)
                {
                    temp[val] = 1;
                }
            }
            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.
                    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;
    }
 
    // Find maximum value that is obtained
    // at index n-1.
    for (val = maxLimit; val >= 0; val--)
    {
        if (dp[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;
}




import java.util.*;
 
public class GFG {
 
    // Function to find maximum possible
    // value of number that can be
    // obtained using array elements.
    public static 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;
 
        // List to store whether a value can
        // be obtained or not up to a certain index.
        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++) {
                // Check for index 0 if the given value
                // val can be obtained by either adding
                // or subtracting arr[0] from num.
                if (ind == 0) {
                    if (num - arr[ind] == val
                        || num + arr[ind] == val) {
                        temp.set(val, true);
                    }
                }
                else {
                    // 1. If arr[ind] is added to
                    // obtain the given val then val -
                    // arr[ind] should be obtainable
                    // from index ind-1.
                    // 2. If arr[ind] is subtracted to
                    // obtain the given val then val +
                    // arr[ind] should be obtainable from
                    // index ind-1. Check for both
                    // conditions.
                    if (val - arr[ind] >= 0
                        && val + arr[ind] <= maxLimit) {
                        // If either of the conditions is
                        // true, then val is obtainable at
                        // index ind.
                        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;
        }
 
        // Find the maximum value that is obtained
        // at index n-1.
        for (val = maxLimit; val >= 0; val--) {
            if (dp.get(val)) {
                return val;
            }
        }
 
        // If no solution exists return -1.
        return -1;
    }
 
    // Driver Code
    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));
    }
}




def findMaxVal(arr, n, num, maxLimit):
    # Vector to store whether a value can be obtained or not
    # up to a certain index.
    dp = [0] * (maxLimit + 1)
 
    for ind in range(n):
        temp = [0] * (maxLimit + 1)
        for val in range(maxLimit + 1):
            # Check for index 0 if the given value val can be
            # obtained by either adding
            # or subtracting arr[0] from num.
            if ind == 0:
                if num - arr[ind] == val or num + arr[ind] == val:
                    temp[val] = 1
            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 0 <= val - arr[ind] <= maxLimit and 0 <= val + arr[ind] <= maxLimit:
                    # If either of the conditions is true, then val is obtainable at index ind.
                    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
 
    # Find maximum value that is obtained at index n-1.
    for val in range(maxLimit, -1, -1):
        if dp[val]:
            return val
 
    # If no solution exists, return -1.
    return -1
 
 
# Driver Code
if __name__ == "__main__":
    num = 1
    arr = [3, 10, 6, 4, 5]
    n = len(arr)
    maxLimit = 15
 
    print(findMaxVal(arr, n, num, maxLimit))




using System;
using System.Collections.Generic;
 
class GFG {
    // Function to find the maximum value that can be formed
    // from the array elements such that it is either the
    // sum or the difference of the given 'num'.
    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]);
 
        // Dynamic Programming approach to find the possible
        // sums or differences.
        for (ind = 0; ind < n; ind++) {
            // Create a temporary list to store the
            // intermediate results.
            List<int> temp = new List<int>(maxLimit + 1);
            temp.AddRange(new int[maxLimit + 1]);
 
            // Check all possible values from 0 to maxLimit.
            for (val = 0; val <= maxLimit; val++) {
                if (ind == 0) {
                    // For the first element in the array,
                    // check if num - arr[ind] or num +
                    // arr[ind] is equal to the current
                    // value 'val'. If so, set temp[val]
                    // to 1.
                    if (num - arr[ind] == val
                        || num + arr[ind] == val) {
                        temp[val] = 1;
                    }
                }
                else {
                    // For subsequent elements, calculate
                    // possible values by taking the
                    // difference or sum of 'val' with the
                    // current element 'arr[ind]'.
                    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]];
                    }
                }
            }
 
            // Update dp with the results from the current
            // iteration.
            dp = temp;
        }
 
        // Find the maximum possible value that can be
        // formed and return it.
        for (val = maxLimit; val >= 0; val--) {
            if (dp[val] == 1) {
                return val;
            }
        }
 
        // If no valid value can be formed, return -1.
        return -1;
    }
 
    static void Main()
    {
        int num = 1;
        int[] arr = { 3, 10, 6, 4, 5 };
        int n = arr.Length;
        int maxLimit = 15;
 
        // Call the FindMaxVal function with the given
        // inputs and print the result.
        Console.WriteLine(
            FindMaxVal(arr, n, num, maxLimit));
    }
}




function findMaxVal(arr, n, num, maxLimit) {
 
    // Variable to represent current index.
    let ind;
     
    //The Variable to show value between
    // 0 and maxLimit.
    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++) {
         
            // Check for index 0 if given value
            // val can be obtained by either adding
            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)
                {
                    // If either of one condition is true
                    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;
    }
     
    // Find maximum value that is obtained at index n-1.
    for (val = maxLimit; val >= 0; val--) {
        if (dp[val]) {
            return val;
        }
    }
     
    // If no solution exists return -1.
    return -1;
}
// Driver Code
 
    const num = 1;
    const arr = [3, 10, 6, 4, 5];
    const n = arr.length;
    const maxLimit = 15;
    console.log(GFG(arr, n, num, maxLimit));

Output
9

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.


Article Tags :