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.
Constraint :
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
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
Steps to solve the problem:
1. Initialize a variable “sum” to 0.
2. Traverse the array arr[] and add each element to sum.
*Shift each element by 50 so that all integers become positive.
3. Initialize a 2D array “dp” of size (n+1)x(MAX*MAX+1) to false.
4. Set dp[0][0] to true.
5. Traverse the array arr[].
*Set k to the minimum value between n and i+1.
*Traverse the dp array for all j from 0 to MAX*MAX+1.
*If dp[k-1][j] is true, set dp[k][j+arr[i]] to true.
6. Initialize two variables, “max_value” and “min_value” to -infinity and +infinity respectively.
7. Traverse the dp array for all i from 0 to MAXMAX+1.
*If dp[n][i] is true, do the following:
*Compute the actual sum “temp” by subtracting 50n from i.
*Compute the product “temp * (sum – temp)” and update the values of max_value and min_value.
8. Print the values of max_value and min_value.
Below is the implementation of the above approach.
C++
#include <bits/stdc++.h>
using namespace std;
#define INF 1e9
#define MAX 50
int minMaxValues( int arr[], int n, int m)
{
int sum = 0;
for ( int i = 0; i < (n + m); i++) {
sum += arr[i];
arr[i] += 50;
}
bool dp[MAX+1][MAX * MAX + 1];
memset (dp, 0, sizeof (dp));
dp[0][0] = 1;
for ( int i = 0; i < (n + m); i++) {
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++) {
if (dp[n][i]) {
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;
}
int main()
{
int n = 2, m = 2;
int arr[] = { 1, 2, 3, 4 };
minMaxValues(arr, n, m);
return 0;
}
|
Java
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)
{
int sum = 0 ;
for ( int i = 0 ; i < (n + m); i++)
{
sum += arr[i];
arr[i] += 50 ;
}
boolean dp[][] =
new boolean [MAX+ 1 ][MAX * MAX + 1 ];
dp[ 0 ][ 0 ] = true ;
for ( int i = 0 ; i < (n + m); i++) {
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++)
{
if (dp[n][i]) {
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" );
}
public static void main(String args[])
{
int n = 2 , m = 2 ;
int []arr = { 1 , 2 , 3 , 4 };
minMaxValues(arr, n, m);
}
}
|
Python3
def minMaxValues(arr, n, m) :
sum = 0
INF = 1000000000
MAX = 50
for i in range ( 0 , (n + m)) :
sum + = arr[i]
arr[i] + = 50
dp = [[ 0 for x in range ( MAX * MAX + 1 )]
for y in range ( MAX + 1 )]
dp[ 0 ][ 0 ] = 1
for i in range ( 0 , (n + m)) :
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 ) :
if (dp[n][i]) :
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))
n = 2
m = 2
arr = [ 1 , 2 , 3 , 4 ]
minMaxValues(arr, n, m)
|
C#
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)
{
int sum = 0;
for ( int i = 0; i < (n + m); i++)
{
sum += arr[i];
arr[i] += 50;
}
bool [,] dp = new bool [MAX+1, MAX * MAX + 1];
dp[0,0] = true ;
for ( int i = 0; i < (n + m); i++) {
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++)
{
if (dp[n,i]) {
/// 50 to avoid negative indexing
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" );
}
public static void Main()
{
int n = 2, m = 2;
int []arr = { 1, 2, 3, 4 };
minMaxValues(arr, n, m);
}
}
|
PHP
<?php
function minMaxValues( $arr , $n , $m )
{
$sum = 0;
$INF = 1000000000;
$MAX = 50;
for ( $i = 0; $i < ( $n + $m ); $i ++)
{
$sum += $arr [ $i ];
$arr [ $i ] += 50;
}
$dp = array ();
for ( $i = 0; $i < $MAX + 1; $i ++)
{
for ( $j = 0; $j < $MAX * $MAX + 1; $j ++)
$dp [ $i ][ $j ] = 0;
}
$dp [0][0] = 1;
for ( $i = 0; $i < ( $n + $m ); $i ++)
{
for ( $k = min( $n , $i + 1);
$k >= 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 ++)
{
if ( $dp [ $n ][ $i ])
{
$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" );
}
$n = 2;
$m = 2;
$arr = [ 1, 2, 3, 4 ];
minMaxValues( $arr , $n , $m );
?>
|
Javascript
<script>
var INF = 1000000000
var MAX = 50
function minMaxValues(arr, n, m)
{
var sum = 0;
for ( var i = 0; i < (n + m); i++) {
sum += arr[i];
arr[i] += 50;
}
var dp = Array.from(Array(MAX+1), ()=> Array(MAX*MAX + 1).fill(0));
dp[0][0] = 1;
for ( var i = 0; i < (n + m); i++) {
for ( var k = Math.min(n, i + 1); k >= 1; k--) {
for ( var j = 0; j < MAX * MAX + 1; j++) {
if (dp[k - 1][j])
dp[k][j + arr[i]] = 1;
}
}
}
var max_value = -INF, min_value = INF;
for ( var i = 0; i < MAX * MAX + 1; i++) {
if (dp[n][i]) {
var temp = i - 50 * n;
max_value = Math.max(max_value, temp * (sum - temp));
min_value = Math.min(min_value, temp * (sum - temp));
}
}
document.write( "Maximum Value: " + max_value
+ "<br>"
+ "Minimum Value: "
+ min_value );
}
var n = 2, m = 2;
var arr =[1, 2, 3, 4];
minMaxValues(arr, n, m);
</script>
|
Output : Maximum Value: 25
Minimum Value: 21
Time Complexity: O(MAX * MAX * (n+m)2).
Auxiliary Space: O(MAX3)
This approach will have a runtime complexity of O(MAX * MAX * (n+m)2).