# Maximum and Minimum Values of an Algebraic Expression

Given an algebraic expression of the form (x1 + x2 + x3 + . . . + xn) * (y1 + y2 + . . . + ym) and
(n + m) integers. Find the maximum and minimum value of the expression using the given
integers.

Consstraint :
n <= 50
m <= 50
-50 <= x1, x2, .. xn <= 50

Examples :

```Input : n = 2, m = 2
arr[] = {1, 2, 3, 4}
Output : Maximum : 25
Minimum : 21
The expression is (x1 + x2) * (y1 + y2) and
the given integers are 1, 2, 3 and 4. Then
maximum value is (1 + 4) * (2 + 3) = 25
whereas minimum value is (4 + 3) * (2 + 1)
= 21.

Input : n = 3, m = 1
arr[] = {1, 2, 3, 4}
Output : Maximum : 24
Minimum : 9
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

A simple solution is to consider all possible combinations of n numbers and remaining m numbers and calculating their values, from which maximum value and minimum value can be derived.

Below is an efficient solution.
The idea is based on limited values of n, m, x1, x2, .. y1, y2, .. Let suppose S be the sum of all the (n + m) numbers in the expression and X be the sum of the n numbers on the left of expression. Obviously, the sum of the m numbers on the right of expression will be represented as (S – X). There can be many possible values of X from the given (n + m) numbers and hence the problem gets reduced to simply iterate through all values of X and keeping track of the minimum and maximum value of X * (S – X).
Now, the problem is equivalent to finding all possible values of X. Since the given numbers are in the range of -50 to 50 and the maximum value of (n + m) is 100, X will lie in between -2500 and 2500 which results into overall 5000 values of X. We will use dynamic programming approach to solve this problem. Consider a dp[i][j] array which can value either 1 or 0, where 1 means X can be equal to j by choosing i numbers from the (n + m) numbers and 0 otherwise. Then for each number k, if dp[i][j] is 1 then dp[i + 1][j + k] is also 1 where k belongs to given (n + m) numbers. Thus, by iterating through all k, we can determine whether a value of X is reachable by choosing a total of n numbers
Below is the implementation of the above approach.

## C++

 `// CPP program to find the maximum ` `// and minimum values of an Algebraic ` `// expression of given form ` `#include ` `using` `namespace` `std; ` ` `  `#define INF 1e9 ` `#define MAX 50 ` ` `  `int` `minMaxValues(``int` `arr[], ``int` `n, ``int` `m) ` `{ ` `    ``// Finding sum of array elements ` `    ``int` `sum = 0; ` `    ``for` `(``int` `i = 0; i < (n + m); i++) { ` `        ``sum += arr[i]; ` ` `  `        ``// shifting the integers by 50 ` `        ``// so that they become positive ` `        ``arr[i] += 50; ` `    ``} ` ` `  `// dp[i][j] represents true if sum ` `// j can be reachable by choosing ` `// i numbers ` `bool` `dp[MAX+1][MAX * MAX + 1]; ` ` `  `    ``// initialize the dp array to 01 ` `    ``memset``(dp, 0, ``sizeof``(dp)); ` ` `  `    ``dp = 1; ` ` `  `    ``// if dp[i][j] is true, that means ` `    ``// it is possible to select i numbers ` `    ``// from (n + m) numbers to sum upto j ` `    ``for` `(``int` `i = 0; i < (n + m); i++) { ` ` `  `        ``// k can be at max n because the ` `        ``// left expression has n numbers ` `        ``for` `(``int` `k = min(n, i + 1); k >= 1; k--) { ` `            ``for` `(``int` `j = 0; j < MAX * MAX + 1; j++) { ` `                ``if` `(dp[k - 1][j]) ` `                    ``dp[k][j + arr[i]] = 1; ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``int` `max_value = -INF, min_value = INF; ` ` `  `    ``for` `(``int` `i = 0; i < MAX * MAX + 1; i++) { ` ` `  `        ``// checking if a particular sum ` `        ``// can be reachable by choosing ` `        ``// n numbers ` `        ``if` `(dp[n][i]) { ` ` `  `            ``// getting the actual sum as ` `            ``// we shifted the numbers by ` `            ``/// 50 to avoid negative indexing ` `            ``// in array ` `            ``int` `temp = i - 50 * n; ` `            ``max_value = max(max_value, temp * (sum - temp)); ` `            ``min_value = min(min_value, temp * (sum - temp)); ` `        ``} ` `    ``} ` `    ``cout << ``"Maximum Value: "` `<< max_value ` `         ``<< ``"\n"` `         ``<< ``"Minimum Value: "` `         ``<< min_value << endl; ` `} ` ` `  `// Driver Code ` `int` `main() ` `{ ` `    ``int` `n = 2, m = 2; ` `    ``int` `arr[] = { 1, 2, 3, 4 }; ` `    ``minMaxValues(arr, n, m); ` `    ``return` `0; ` `} `

## Java

 `// Java program to find the maximum ` `// and minimum values of an Algebraic ` `// expression of given form ` `import` `java.io.*; ` `import` `java.lang.*; ` ` `  `public` `class` `GFG { ` `     `  `    ``static` `double` `INF = 1e9; ` `    ``static` `int` `MAX = ``50``; ` ` `  `    ``static` `void` `minMaxValues(``int` `[]arr,  ` `                              ``int` `n, ``int` `m) ` `    ``{ ` `         `  `        ``// Finding sum of array elements ` `        ``int` `sum = ``0``; ` `        ``for` `(``int` `i = ``0``; i < (n + m); i++) ` `        ``{ ` `            ``sum += arr[i]; ` `     `  `            ``// shifting the integers by 50 ` `            ``// so that they become positive ` `            ``arr[i] += ``50``; ` `        ``} ` `     `  `        ``// dp[i][j] represents true if sum ` `        ``// j can be reachable by choosing ` `        ``// i numbers ` `        ``boolean` `dp[][] =  ` `             ``new` `boolean``[MAX+``1``][MAX * MAX + ``1``]; ` `     `  `        ``dp[``0``][``0``] = ``true``; ` `     `  `        ``// if dp[i][j] is true, that means ` `        ``// it is possible to select i numbers ` `        ``// from (n + m) numbers to sum upto j ` `        ``for` `(``int` `i = ``0``; i < (n + m); i++) { ` `     `  `            ``// k can be at max n because the ` `            ``// left expression has n numbers ` `            ``for` `(``int` `k = Math.min(n, i + ``1``); k >= ``1``; k--)  ` `            ``{ ` `                ``for` `(``int` `j = ``0``; j < MAX * MAX + ``1``; j++) ` `                ``{ ` `                    ``if` `(dp[k - ``1``][j]) ` `                        ``dp[k][j + arr[i]] = ``true``; ` `                ``} ` `            ``} ` `        ``} ` `     `  `        ``double` `max_value = -``1` `* INF, min_value = INF; ` `     `  `        ``for` `(``int` `i = ``0``; i < MAX * MAX + ``1``; i++) ` `        ``{ ` `     `  `            ``// checking if a particular sum ` `            ``// can be reachable by choosing ` `            ``// n numbers ` `            ``if` `(dp[n][i]) { ` `     `  `                ``// getting the actual sum as ` `                ``// we shifted the numbers by ` `                ``/// 50 to avoid negative indexing ` `                ``// in array ` `                ``int` `temp = i - ``50` `* n; ` `                ``max_value = Math.max(max_value, temp * ` `                                        ``(sum - temp)); ` `                                             `  `                ``min_value = Math.min(min_value, temp *  ` `                                        ``(sum - temp)); ` `            ``} ` `        ``} ` `         `  `        ``System.out.print(``"Maximum Value: "` `+  ` `                     ``(``int``)max_value + ``"\n"` `+  ` `          ``"Minimum Value: "` `+ (``int``)min_value + ``"\n"``); ` `    ``} ` ` `  `    ``// Driver Code ` `    ``public` `static` `void` `main(String args[]) ` `    ``{ ` `        ``int` `n = ``2``, m = ``2``; ` `        ``int` `[]arr = { ``1``, ``2``, ``3``, ``4` `}; ` `        ``minMaxValues(arr, n, m); ` `    ``} ` `} ` ` `  `// This code is contributed by Manish Shaw ` `// (manishshaw1) `

## Python3

 `# Python3 program to find the  ` `# maximum and minimum values  ` `# of an Algebraic expression  ` `# of given form ` `def` `minMaxValues(arr, n, m) :      ` `    ``# Finding sum of ` `    ``# array elements ` `    ``sum` `=` `0` `    ``INF ``=` `1000000000` `    ``MAX` `=` `50` `    ``for` `i ``in` `range``(``0``, (n ``+` `m)) : ` `        ``sum` `+``=` `arr[i] ` ` `  `        ``# shifting the integers by 50 ` `        ``# so that they become positive ` `        ``arr[i] ``+``=` `50` ` `  `    ``# dp[i][j] represents true  ` `    ``# if sum j can be reachable ` `    ``# by choosing i numbers ` `    ``dp ``=` `[[``0` `for` `x ``in` `range``(``MAX` `*` `MAX` `+` `1``)] ` `                  ``for` `y ``in` `range``( ``MAX` `+` `1``)] ` `     `  `    ``dp[``0``][``0``] ``=` `1` ` `  `    ``# if dp[i][j] is true, that  ` `    ``# means it is possible to  ` `    ``# select i numbers from (n + m) ` `    ``# numbers to sum upto j ` `    ``for` `i ``in` `range``(``0``, (n ``+` `m)) :  ` `         `  `        ``# k can be at max n because the ` `        ``# left expression has n numbers ` `        ``for` `k ``in` `range``(``min``(n, i ``+` `1``), ``0``, ``-``1``) : ` `            ``for` `j ``in` `range``(``0``, ``MAX` `*` `MAX` `+` `1``) : ` `                ``if` `(dp[k ``-` `1``][j]) : ` `                    ``dp[k][j ``+` `arr[i]] ``=` `1` ` `  `    ``max_value ``=` `-``1` `*` `INF  ` `    ``min_value ``=` `INF ` ` `  `    ``for` `i ``in` `range``(``0``, ``MAX` `*` `MAX` `+` `1``) : ` ` `  `        ``# checking if a particular  ` `        ``# sum can be reachable by  ` `        ``# choosing n numbers ` `        ``if` `(dp[n][i]) : ` ` `  `            ``# getting the actual sum  ` `            ``# as we shifted the numbers  ` `            ``# by 50 to avoid negative  ` `            ``# indexing in array ` `            ``temp ``=` `i ``-` `50` `*` `n ` `            ``max_value ``=` `max``(max_value,  ` `                         ``temp ``*` `(``sum` `-` `temp)) ` `                                         `  `            ``min_value ``=` `min``(min_value, ` `                         ``temp ``*` `(``sum` `-` `temp)) ` `     `  `    ``print` `(``"Maximum Value: {}\nMinimum Value: {}"` `                 ``.``format``(max_value, min_value)) ` ` `  `# Driver Code ` `n ``=` `2` `m ``=` `2` `arr ``=` `[ ``1``, ``2``, ``3``, ``4` `] ` ` `  `minMaxValues(arr, n, m)  ` ` `  `# This code is contributed by  ` `# Manish Shaw(manishshaw1) `

## C#

 `// C# program to find the maximum ` `// and minimum values of an Algebraic ` `// expression of given form ` `using` `System; ` `using` `System.Collections.Generic; ` ` `  `class` `GFG { ` `     `  `    ``static` `double` `INF = 1e9; ` `    ``static` `int` `MAX = 50; ` ` `  `    ``static` `void` `minMaxValues(``int` `[]arr, ``int` `n, ``int` `m) ` `    ``{ ` `         `  `        ``// Finding sum of array elements ` `        ``int` `sum = 0; ` `        ``for` `(``int` `i = 0; i < (n + m); i++) ` `        ``{ ` `            ``sum += arr[i]; ` `     `  `            ``// shifting the integers by 50 ` `            ``// so that they become positive ` `            ``arr[i] += 50; ` `        ``} ` `     `  `    ``// dp[i][j] represents true if sum ` `    ``// j can be reachable by choosing ` `    ``// i numbers ` `        ``bool``[,] dp = ``new` `bool``[MAX+1, MAX * MAX + 1]; ` `     `  `        ``dp[0,0] = ``true``; ` `     `  `        ``// if dp[i][j] is true, that means ` `        ``// it is possible to select i numbers ` `        ``// from (n + m) numbers to sum upto j ` `        ``for` `(``int` `i = 0; i < (n + m); i++) { ` `     `  `            ``// k can be at max n because the ` `            ``// left expression has n numbers ` `            ``for` `(``int` `k = Math.Min(n, i + 1); k >= 1; k--)  ` `            ``{ ` `                ``for` `(``int` `j = 0; j < MAX * MAX + 1; j++) ` `                ``{ ` `                    ``if` `(dp[k - 1,j]) ` `                        ``dp[k,j + arr[i]] = ``true``; ` `                ``} ` `            ``} ` `        ``} ` `     `  `        ``double` `max_value = -1 * INF, min_value = INF; ` `     `  `        ``for` `(``int` `i = 0; i < MAX * MAX + 1; i++) ` `        ``{ ` `     `  `            ``// checking if a particular sum ` `            ``// can be reachable by choosing ` `            ``// n numbers ` `            ``if` `(dp[n,i]) { ` `     `  `                ``// getting the actual sum as ` `                ``// we shifted the numbers by ` `                ``/// 50 to avoid negative indexing ` `                ``// in array ` `                ``int` `temp = i - 50 * n; ` `                ``max_value = Math.Max(max_value, temp * ` `                                          ``(sum - temp)); ` `                                           `  `                ``min_value = Math.Min(min_value, temp *  ` `                                          ``(sum - temp)); ` `            ``} ` `        ``} ` `         `  `        ``Console.WriteLine(``"Maximum Value: "` `+ max_value ` `         ``+ ``"\n"` `+ ``"Minimum Value: "` `+ min_value + ``"\n"``); ` `    ``} ` ` `  `    ``// Driver Code ` `    ``public` `static` `void` `Main() ` `    ``{ ` `        ``int` `n = 2, m = 2; ` `        ``int` `[]arr = { 1, 2, 3, 4 }; ` `        ``minMaxValues(arr, n, m); ` `    ``} ` `} ` ` `  `// This code is contributed by Manish Shaw ` `// (manishshaw1) `

## PHP

 `= 1; ``\$k``--)  ` `        ``{ ` `            ``for` `(``\$j` `= 0; ``\$j` `< ``\$MAX` `*  ` `                              ``\$MAX` `+ 1; ``\$j``++) ` `            ``{ ` `                ``if` `(``\$dp``[``\$k` `- 1][``\$j``]) ` `                    ``\$dp``[``\$k``][``\$j` `+ ``\$arr``[``\$i``]] = 1; ` `            ``} ` `        ``} ` `    ``} ` ` `  `    ``\$max_value` `= -1 * ``\$INF``;  ` `    ``\$min_value` `= ``\$INF``; ` ` `  `    ``for` `(``\$i` `= 0; ``\$i` `< ``\$MAX` `* ``\$MAX` `+ 1; ``\$i``++) ` `    ``{ ` ` `  `        ``// checking if a particular  ` `        ``// sum can be reachable by  ` `        ``// choosing n numbers ` `        ``if` `(``\$dp``[``\$n``][``\$i``])  ` `        ``{ ` ` `  `            ``// getting the actual sum  ` `            ``// as we shifted the numbers  ` `            ``// by 50 to avoid negative  ` `            ``// indexing in array ` `            ``\$temp` `= ``\$i` `- 50 * ``\$n``; ` `            ``\$max_value` `= max(``\$max_value``, ``\$temp` `* ` `                                ``(``\$sum` `- ``\$temp``)); ` `                                         `  `            ``\$min_value` `= min(``\$min_value``, ``\$temp` `*  ` `                                ``(``\$sum` `- ``\$temp``)); ` `        ``} ` `    ``} ` `     `  `    ``echo` `(``"Maximum Value: "``. ``\$max_value``. ``"\n"``.  ` `          ``"Minimum Value: "``. ``\$min_value``. ``"\n"``); ` `} ` ` `  `// Driver Code ` `\$n` `= 2; ` `\$m` `= 2; ` `\$arr` `= [ 1, 2, 3, 4 ]; ` ` `  `minMaxValues(``\$arr``, ``\$n``, ``\$m``);  ` ` `  `// This code is contributed by  ` `// Manish Shaw(manishshaw1) ` `?> `

Output :

```Maximum Value: 25
Minimum Value: 21
```

This approach will have a runtime complexity of O(MAX * MAX * (n+m)2).

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.

My Personal Notes arrow_drop_up Check out this Author's contributed articles.

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.

Improved By : manishshaw1