给定形式为(x 1 + x 2 + x 3 + .. + x n )*(y 1 + y 2 + …. + y m )的代数表达式,
(n + m)个整数。使用给定找到表达式的最大值和最小值
整数。
Consstraint :
n <= 50
m <= 50
-50 <= x1, x2, .. xn <= 50
例子 :
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
一个简单的解决方案是考虑n个数字和其余m个数字的所有可能组合,并计算它们的值,从中可以得出最大值和最小值。
下面是一个有效的解决方案。
这个想法是基于n,m,x1,x2,.. y1,y2,..的有限值。假设S是表达式中所有(n + m)个数的和,X是n的和。表达式左侧的数字。显然,表达式右边的m个数字的总和将表示为(S – X)。从给定的(n + m)个数中可以有很多X值,因此问题被简化为简单地遍历X的所有值并跟踪X *(S – X)的最小值和最大值。
现在,问题等同于找到X的所有可能值。由于给定的数字在-50到50的范围内,并且(n + m)的最大值是100,因此X介于-2500和2500之间结果总计为X的5000个值。我们将使用动态编程方法来解决此问题。考虑一个dp [i] [j]数组,其值可以为1或0,其中1表示通过从(n + m)个数字中选择i个数字,X可以等于j,否则为0。那么对于每个数k,如果dp [i] [j]为1,则dp [i + 1] [j + k]也是1,其中k属于给定(n + m)个数。因此,通过遍历所有k,我们可以通过选择总共n个数字来确定X的值是否可达到
下面是上述方法的实现。
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[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 (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)
?>
Maximum Value: 25
Minimum Value: 21
这种方法的运行时复杂度为O(MAX * MAX *(n + m) 2 )。