通过从给定数组中选择相同长度的子序列来最大化对的乘积之和
给定两个长度分别为N和M的整数数组A[]和B[] ,任务是从每个数组中选择任何相同长度的子序列,使得子序列中相应索引处的对的乘积之和最大化。
例子:
Input: A = {4, -1, -3, 3}, B = {-4, 0, 5}
Output: 27
Explanation: Choosing subsequence {-3, 3} from A and subsequence {-4, 5} from B will give the maximum sum,
i.e. = (-3)*(-4) + 3*5 = 12 + 15 = 27
Input: A = {-5, -1}, B = {2, 1, 4}
Output: -1
Explanation: The maximum sum of products possible is (-1)*1 = -1
朴素方法:仔细观察时,实际上我们需要从每个数组中找到等长(> = 1)的最佳子序列,使得这些子序列中元素的乘积之和最大。
So by using hit and trial method, we can use a recursive approach with to “choose or not choose” each element from both arrays, and find the optimal subsequence from all possible subsequences.
下面是递归方法的实现。
C++
// C++ program to Find the maximum summation of
// products of pair of elements from two arrays
// with negative numbers.
#include
using namespace std;
int MaxSOP(vector& a, vector& b,
int n, int m,
int taken)
{
// To ensure we take
// at least one element
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take
// any more elements that
// is come to an end
// of any array return 0
else if ((n == 0 || m == 0)
&& taken != 0)
return 0;
// Take the product & increment taken
// skip element from a[]
// skip element from b[]
return max(
{ a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1,
m - 1, taken + 1),
MaxSOP(a, b, n - 1, m, taken),
MaxSOP(a, b, n, m - 1, taken) });
}
// Driver code
int main()
{
vector a = { 4, -1, -3, 3 };
vector b = { -4, 0, 5 };
int ans = MaxSOP(a, b, a.size(),
b.size(), 0);
cout << ans << endl;
return 0;
}
Java
// JAVA program to Find the maximum summation of
// products of pair of elements from two arrays
// with negative numbers.
import java.util.*;
class GFG {
public static int MaxSOP(int a[], int b[], int n, int m,
int taken)
{
// To ensure we take
// at least one element
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take
// any more elements that
// is come to an end
// of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
// Take the product & increment taken
// skip element from a[]
// skip element from b[]
return Math.max(
Math.max(
a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1, m - 1, taken + 1),
MaxSOP(a, b, n - 1, m, taken)),
MaxSOP(a, b, n, m - 1, taken));
}
// Driver code
public static void main(String[] args)
{
int a[] = { 4, -1, -3, 3 };
int b[] = { -4, 0, 5 };
int ans = MaxSOP(a, b, a.length, b.length, 0);
System.out.print(ans);
}
}
// This code is contributed by rakeshsahni
Python3
# Python3 program to Find the maximum summation of
# products of pair of elements from two arrays
# with negative numbers.
def MaxSOP(a, b, n, m, taken):
# To ensure we take
# at least one element
if ((n == 0 or m == 0) and taken == 0):
return -9999999
# Else if we cant take
# any more elements that
# is come to an end
# of any array return 0
elif ((n == 0 or m == 0) and taken != 0):
return 0
# Take the product & increment taken
# skip element from a[]
# skip element from b[]
return max(a[n - 1] * b[m - 1] + MaxSOP(a, b, n - 1,m - 1, taken + 1),MaxSOP(a, b, n - 1, m, taken),MaxSOP(a, b, n, m - 1, taken))
# Driver code
a = [ 4, -1, -3, 3 ]
b = [ -4, 0, 5 ]
ans = MaxSOP(a, b, len(a), len(b), 0)
print(ans)
# This code is contributed by shinjanpatra
C#
// C# program to Find the maximum summation of
// products of pair of elements from two arrays
// with negative numbers.
using System;
class GFG {
static int MaxSOP(int[] a, int[] b, int n, int m,
int taken)
{
// To ensure we take
// at least one element
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take
// any more elements that
// is come to an end
// of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
// Take the product & increment taken
// skip element from a[]
// skip element from b[]
return Math.Max(
a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1, m - 1, taken + 1),
Math.Max(MaxSOP(a, b, n - 1, m, taken),
MaxSOP(a, b, n, m - 1, taken)));
}
// Driver code
public static void Main()
{
int[] a = { 4, -1, -3, 3 };
int[] b = { -4, 0, 5 };
int ans = MaxSOP(a, b, a.Length, b.Length, 0);
Console.Write(ans);
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
C++
// C++ program to Find the maximum summation of
// products of pair of elements from two arrays
// with negative numbers.
#include
using namespace std;
// 3D array for memoization
int t[101][101][101];
int MaxSOP(vector& a, vector& b,
int n, int m,
int taken)
{
// If taken = 0, therefore empty subsequence
// So return highly negative value
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take any more elements
// that is come to an end
// of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
if (t[n][m][taken] != -1)
// If value is previously calculated
// return it directly
return t[n][m][taken];
return t[n][m][taken]
= max({ a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1,
m - 1,
taken + 1),
MaxSOP(a, b, n - 1, m, taken),
MaxSOP(a, b, n, m - 1, taken) });
}
// Driver code
int main()
{
vector a = { 4, -1, -3, 3 };
vector b = { -4, 0, 5 };
memset(t, -1, sizeof(t));
int ans = MaxSOP(a, b, a.size(),
b.size(), 0);
cout << ans << endl;
return 0;
}
Java
// Java program to Find the maximum summation of
// products of pair of elements from two arrays
// with negative numbers.
import java.util.*;
public class GFG {
// 3D array for memoization
static int t[][][] = new int[101][101][101];
static int MaxSOP(int[] a, int[] b, int n, int m,
int taken)
{
// If taken = 0, therefore empty subsequence
// So return highly negative value
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take any more elements
// that is come to an end
// of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
if (t[n][m][taken] != -1)
// If value is previously calculated
// return it directly
return t[n][m][taken];
return t[n][m][taken]
= Math.max(
a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1, m - 1, taken + 1),
Math.max(MaxSOP(a, b, n - 1, m, taken),
MaxSOP(a, b, n, m - 1, taken)));
}
// Driver code
public static void main(String args[])
{
int[] a = { 4, -1, -3, 3 };
int[] b = { -4, 0, 5 };
for (int i = 0; i < 101; i++) {
for (int j = 0; j < 101; j++) {
for (int k = 0; k < 101; k++) {
t[i][j][k] = -1;
}
}
}
int ans = MaxSOP(a, b, a.length, b.length, 0);
System.out.println(ans);
}
}
// This code is contributed by Samim Hossain Mondal.
Python3
# Python program to Find the maximum summation of
# products of pair of elements from two arrays
# with negative numbers.
# 3D array for memoization
t = [[ [-1 for col in range(101)] for col in range(101)] for row in range(101)]
def MaxSOP(a, b, n, m, taken):
global t
# If taken = 0, therefore empty subsequence
# So return highly negative value
if ((n == 0 or m == 0) and taken == 0):
return -9999999
# Else if we cant take any more elements
# that is come to an end
# of any array return 0
elif ((n == 0 or m == 0) and taken != 0):
return 0
if (t[n][m][taken] != -1):
# If value is previously calculated
# return it directly
return t[n][m][taken]
t[n][m][taken] = max(max(a[n - 1] * b[m - 1] + MaxSOP(a, b, n - 1,m - 1,taken + 1),MaxSOP(a, b, n - 1, m, taken)),MaxSOP(a, b, n, m - 1, taken))
return t[n][m][taken]
# Driver code
a = [ 4, -1, -3, 3 ]
b = [ -4, 0, 5 ]
ans = MaxSOP(a, b, len(a), len(b), 0)
print(ans)
# This code is contributed by shinjanpatra
C#
// C# program to Find the maximum summation of
// products of pair of elements from two arrays
// with negative numbers.
using System;
class GFG {
// 3D array for memoization
static int[, , ] t = new int[101, 101, 101];
static int MaxSOP(int[] a, int[] b, int n, int m,
int taken)
{
// If taken = 0, therefore empty subsequence
// So return highly negative value
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take any more elements
// that is come to an end
// of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
if (t[n, m, taken] != -1)
// If value is previously calculated
// return it directly
return t[n, m, taken];
return t[n, m, taken]
= Math.Max(
a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1, m - 1, taken + 1),
Math.Max(MaxSOP(a, b, n - 1, m, taken),
MaxSOP(a, b, n, m - 1, taken)));
}
// Driver code
public static void Main()
{
int[] a = { 4, -1, -3, 3 };
int[] b = { -4, 0, 5 };
for (int i = 0; i < 101; i++) {
for (int j = 0; j < 101; j++) {
for (int k = 0; k < 101; k++) {
t[i, j, k] = -1;
}
}
}
int ans = MaxSOP(a, b, a.Length, b.Length, 0);
Console.WriteLine(ans);
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
C++
// C++ code to implement the approach
#include
using namespace std;
// Dp array
int t[101][101][2];
// Function to count the maximum possible sum
int MaxSOP(vector& a, vector& b,
int n, int m, int taken)
{
// If taken==0, therefore empty subsequence
// so return highly negative value
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take any more elements
// that is come to an end of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
// If the value is pre-calculated
// simply return it
if (t[n][m][taken == 0 ? 0 : 1] != -1)
return t[n][m][taken == 0 ? 0 : 1];
// Return and store the calculated value
return t[n][m][taken == 0 ? 0 : 1]
= max({ a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1, m - 1,
taken + 1),
MaxSOP(a, b, n - 1, m, taken),
MaxSOP(a, b, n, m - 1, taken) });
}
// Driver code
int main()
{
vector a = { 4, -1, -3, 3 };
vector b = { -4, 0, 5 };
memset(t, -1, sizeof(t));
int ans = MaxSOP(a, b, a.size(), b.size(), 0);
cout << ans << endl;
return 0;
}
Java
// Java program to Find the maximum summation of
// products of pair of elements from two arrays
// with negative numbers.
import java.util.*;
class GFG {
// DP array
static int t[][][] = new int[101][101][101];
static int MaxSOP(int[] a, int[] b, int n, int m,
int taken)
{
// If taken = 0, therefore empty subsequence
// So return highly negative value
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take any more elements
// that is come to an end
// of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
// If value is previously calculated
// return it directly
if (t[n][m][taken == 0 ? 0 : 1] != -1)
return t[n][m][taken == 0 ? 0 : 1];
return t[n][m][taken == 0 ? 0 : 1]
= Math.max(
a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1, m - 1, taken + 1),
Math.max(MaxSOP(a, b, n - 1, m, taken),
MaxSOP(a, b, n, m - 1, taken)));
}
// Driver code
public static void main(String args[])
{
int[] a = { 4, -1, -3, 3 };
int[] b = { -4, 0, 5 };
for (int i = 0; i < 101; i++) {
for (int j = 0; j < 101; j++) {
for (int k = 0; k < 101; k++) {
t[i][j][k] = -1;
}
}
}
int ans = MaxSOP(a, b, a.length, b.length, 0);
System.out.println(ans);
}
}
// This code is contributed by Karandeep1234
C#
// C# code to implement the approach
using System;
using System.Collections.Generic;
class GFG {
// Dp array
static int[, , ] t = new int[101, 101, 2];
// Function to count the maximum possible sum
static int MaxSOP(List a, List b, int n,
int m, int taken)
{
// If taken==0, therefore empty subsequence
// so return highly negative value
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take any more elements
// that is come to an end of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
// If the value is pre-calculated
// simply return it
if (t[n, m, taken == 0 ? 0 : 1] != -1)
return t[n, m, taken == 0 ? 0 : 1];
// Return and store the calculated value
return t[n, m, taken == 0 ? 0 : 1] = Math.Max(
Math.Max(a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1, m - 1,
taken + 1),
MaxSOP(a, b, n - 1, m, taken)),
MaxSOP(a, b, n, m - 1, taken));
}
// Driver code
public static void Main()
{
List a = new List() { 4, -1, -3, 3 };
List b = new List() { -4, 0, 5 };
for (int i = 0; i < 101; i++)
for (int j = 0; j < 101; j++)
for (int k = 0; k < 2; k++)
t[i, j, k] = -1;
int ans = MaxSOP(a, b, a.Count, b.Count, 0);
Console.Write(ans);
}
}
// This code is contributed by ukasp.
27
时间复杂度: O(3 N ),因为我们调用函数3 次。
辅助空间:O(1)(不考虑递归堆栈)
高效方法:由于递归,朴素方法的指数时间复杂度可以通过动态规划进行优化。
Memoize the recursive code and store the results in a matrix, so that when an overlapping sub-problem is found, directly return the result of it from the matrix. This will reduce the depth of the recursion and reduce the time complexity.
As we have three changing parameters, we will require 3D DP-array to store the values
下面是上述方法的实现:
C++
// C++ program to Find the maximum summation of
// products of pair of elements from two arrays
// with negative numbers.
#include
using namespace std;
// 3D array for memoization
int t[101][101][101];
int MaxSOP(vector& a, vector& b,
int n, int m,
int taken)
{
// If taken = 0, therefore empty subsequence
// So return highly negative value
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take any more elements
// that is come to an end
// of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
if (t[n][m][taken] != -1)
// If value is previously calculated
// return it directly
return t[n][m][taken];
return t[n][m][taken]
= max({ a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1,
m - 1,
taken + 1),
MaxSOP(a, b, n - 1, m, taken),
MaxSOP(a, b, n, m - 1, taken) });
}
// Driver code
int main()
{
vector a = { 4, -1, -3, 3 };
vector b = { -4, 0, 5 };
memset(t, -1, sizeof(t));
int ans = MaxSOP(a, b, a.size(),
b.size(), 0);
cout << ans << endl;
return 0;
}
Java
// Java program to Find the maximum summation of
// products of pair of elements from two arrays
// with negative numbers.
import java.util.*;
public class GFG {
// 3D array for memoization
static int t[][][] = new int[101][101][101];
static int MaxSOP(int[] a, int[] b, int n, int m,
int taken)
{
// If taken = 0, therefore empty subsequence
// So return highly negative value
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take any more elements
// that is come to an end
// of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
if (t[n][m][taken] != -1)
// If value is previously calculated
// return it directly
return t[n][m][taken];
return t[n][m][taken]
= Math.max(
a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1, m - 1, taken + 1),
Math.max(MaxSOP(a, b, n - 1, m, taken),
MaxSOP(a, b, n, m - 1, taken)));
}
// Driver code
public static void main(String args[])
{
int[] a = { 4, -1, -3, 3 };
int[] b = { -4, 0, 5 };
for (int i = 0; i < 101; i++) {
for (int j = 0; j < 101; j++) {
for (int k = 0; k < 101; k++) {
t[i][j][k] = -1;
}
}
}
int ans = MaxSOP(a, b, a.length, b.length, 0);
System.out.println(ans);
}
}
// This code is contributed by Samim Hossain Mondal.
Python3
# Python program to Find the maximum summation of
# products of pair of elements from two arrays
# with negative numbers.
# 3D array for memoization
t = [[ [-1 for col in range(101)] for col in range(101)] for row in range(101)]
def MaxSOP(a, b, n, m, taken):
global t
# If taken = 0, therefore empty subsequence
# So return highly negative value
if ((n == 0 or m == 0) and taken == 0):
return -9999999
# Else if we cant take any more elements
# that is come to an end
# of any array return 0
elif ((n == 0 or m == 0) and taken != 0):
return 0
if (t[n][m][taken] != -1):
# If value is previously calculated
# return it directly
return t[n][m][taken]
t[n][m][taken] = max(max(a[n - 1] * b[m - 1] + MaxSOP(a, b, n - 1,m - 1,taken + 1),MaxSOP(a, b, n - 1, m, taken)),MaxSOP(a, b, n, m - 1, taken))
return t[n][m][taken]
# Driver code
a = [ 4, -1, -3, 3 ]
b = [ -4, 0, 5 ]
ans = MaxSOP(a, b, len(a), len(b), 0)
print(ans)
# This code is contributed by shinjanpatra
C#
// C# program to Find the maximum summation of
// products of pair of elements from two arrays
// with negative numbers.
using System;
class GFG {
// 3D array for memoization
static int[, , ] t = new int[101, 101, 101];
static int MaxSOP(int[] a, int[] b, int n, int m,
int taken)
{
// If taken = 0, therefore empty subsequence
// So return highly negative value
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take any more elements
// that is come to an end
// of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
if (t[n, m, taken] != -1)
// If value is previously calculated
// return it directly
return t[n, m, taken];
return t[n, m, taken]
= Math.Max(
a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1, m - 1, taken + 1),
Math.Max(MaxSOP(a, b, n - 1, m, taken),
MaxSOP(a, b, n, m - 1, taken)));
}
// Driver code
public static void Main()
{
int[] a = { 4, -1, -3, 3 };
int[] b = { -4, 0, 5 };
for (int i = 0; i < 101; i++) {
for (int j = 0; j < 101; j++) {
for (int k = 0; k < 101; k++) {
t[i, j, k] = -1;
}
}
}
int ans = MaxSOP(a, b, a.Length, b.Length, 0);
Console.WriteLine(ans);
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
27
时间复杂度: O(N 3 )。
辅助空间: O(N 3 ),用于使用额外的 3D 数组。
更有效的方法:可以通过使用以下观察减少状态来进一步优化上述方法:
In the above dynamic programming approach, we are concerned with only two states of taken: either 0 or not 0.
So instead of keeping multiple states of taken, it can be bound to two states 0 and 1.
下面是上述方法的实现。
C++
// C++ code to implement the approach
#include
using namespace std;
// Dp array
int t[101][101][2];
// Function to count the maximum possible sum
int MaxSOP(vector& a, vector& b,
int n, int m, int taken)
{
// If taken==0, therefore empty subsequence
// so return highly negative value
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take any more elements
// that is come to an end of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
// If the value is pre-calculated
// simply return it
if (t[n][m][taken == 0 ? 0 : 1] != -1)
return t[n][m][taken == 0 ? 0 : 1];
// Return and store the calculated value
return t[n][m][taken == 0 ? 0 : 1]
= max({ a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1, m - 1,
taken + 1),
MaxSOP(a, b, n - 1, m, taken),
MaxSOP(a, b, n, m - 1, taken) });
}
// Driver code
int main()
{
vector a = { 4, -1, -3, 3 };
vector b = { -4, 0, 5 };
memset(t, -1, sizeof(t));
int ans = MaxSOP(a, b, a.size(), b.size(), 0);
cout << ans << endl;
return 0;
}
Java
// Java program to Find the maximum summation of
// products of pair of elements from two arrays
// with negative numbers.
import java.util.*;
class GFG {
// DP array
static int t[][][] = new int[101][101][101];
static int MaxSOP(int[] a, int[] b, int n, int m,
int taken)
{
// If taken = 0, therefore empty subsequence
// So return highly negative value
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take any more elements
// that is come to an end
// of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
// If value is previously calculated
// return it directly
if (t[n][m][taken == 0 ? 0 : 1] != -1)
return t[n][m][taken == 0 ? 0 : 1];
return t[n][m][taken == 0 ? 0 : 1]
= Math.max(
a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1, m - 1, taken + 1),
Math.max(MaxSOP(a, b, n - 1, m, taken),
MaxSOP(a, b, n, m - 1, taken)));
}
// Driver code
public static void main(String args[])
{
int[] a = { 4, -1, -3, 3 };
int[] b = { -4, 0, 5 };
for (int i = 0; i < 101; i++) {
for (int j = 0; j < 101; j++) {
for (int k = 0; k < 101; k++) {
t[i][j][k] = -1;
}
}
}
int ans = MaxSOP(a, b, a.length, b.length, 0);
System.out.println(ans);
}
}
// This code is contributed by Karandeep1234
C#
// C# code to implement the approach
using System;
using System.Collections.Generic;
class GFG {
// Dp array
static int[, , ] t = new int[101, 101, 2];
// Function to count the maximum possible sum
static int MaxSOP(List a, List b, int n,
int m, int taken)
{
// If taken==0, therefore empty subsequence
// so return highly negative value
if ((n == 0 || m == 0) && taken == 0)
return -9999999;
// Else if we cant take any more elements
// that is come to an end of any array return 0
else if ((n == 0 || m == 0) && taken != 0)
return 0;
// If the value is pre-calculated
// simply return it
if (t[n, m, taken == 0 ? 0 : 1] != -1)
return t[n, m, taken == 0 ? 0 : 1];
// Return and store the calculated value
return t[n, m, taken == 0 ? 0 : 1] = Math.Max(
Math.Max(a[n - 1] * b[m - 1]
+ MaxSOP(a, b, n - 1, m - 1,
taken + 1),
MaxSOP(a, b, n - 1, m, taken)),
MaxSOP(a, b, n, m - 1, taken));
}
// Driver code
public static void Main()
{
List a = new List() { 4, -1, -3, 3 };
List b = new List() { -4, 0, 5 };
for (int i = 0; i < 101; i++)
for (int j = 0; j < 101; j++)
for (int k = 0; k < 2; k++)
t[i, j, k] = -1;
int ans = MaxSOP(a, b, a.Count, b.Count, 0);
Console.Write(ans);
}
}
// This code is contributed by ukasp.
27
时间复杂度: O(N*M)
辅助空间: O(N*M)