Maximize sum of pairwise products generated from the given Arrays

Given three arrays arr1[], arr2[] and arr3[] of length N1, N2, and N3 respectively, the task is to find the maximum sum possible by adding the products of pairs taken from different arrays.
Note: Each array element can be a part of a single pair.
Examples:
Input: arr1[] = {3, 5}, arr2[] = {2, 1}, arr3[] = {4, 3, 5}
Output : 43
Explanation
After sorting the arrays in descending order, following modifications are obtained: arr1[] = {5, 3}, arr2[] = {2, 1}, arr3[] = {5, 4, 3}.
Therefore, maximized product = (arr1[0] * arr3[0]) + (arr1[1] * arr3[1]) + (arr2[0] * arr3[2]) = (5*5 + 3*4 + 2*3) = 43Input: arr1[] = {3, 5, 9, 8, 7}, arr2[] = {6}, arr3[] = {3, 5}
Output : 115
Explanation
Sort the arrays in descending order, the following modifications are obtained: arr1[] = {9, 8, 7, 5, 3}, arr2[] = {6}, arr3[] = {5, 3}.
Therefore, maximized product = (arr1[0] * arr2[0]) + (arr1[1] * arr3[0]) + (arr1[2] * arr3[1]) = (9*6 + 8*5 + 7*3) = 155
Approach: The given problem can be solved using a 3D Memoization table to store the maximum sums for all possible combinations of pairs. Suppose i, j, k are the number of elements taken from the arrays arr1[], arr2[] and arr3[] respectively to form pairs, then the memorization table dp[][][] will store the maximum possible sum of products generated from this combination of elements in dp[i][j][k]. 
Follow the below steps to solve the problem-
- Sort the given arrays in descending order.
- Initialize a dp table dp[][][], where dp[i][j][k] store the maximum sum obtained by taking i largest numbers from the first array, j largest numbers from the second array, and k largest numbers from the third array.
- For every i, j, and kth element from the three arrays respectively, check for all possible pairs and calculate the maximum sum possible by considering each pair and memoize the maximum sum obtained for further computation.
- Finally, print the maximum possible sum returned by the dp[][][] matrix.
Below is the implementation of the above approach:
C++
| // C++ Program to implement// the above approach#include <bits/stdc++.h>usingnamespacestd;#define maxN 201// Variables which represent// the size of the arrayintn1, n2, n3;// Stores the resultsintdp[maxN][maxN][maxN];// Function to return the// maximum possible sumintgetMaxSum(inti, intj,              intk, intarr1[],              intarr2[], intarr3[]){    // Stores the count of    // arrays processed    intcnt = 0;    if(i >= n1)        cnt++;    if(j >= n2)        cnt++;    if(k >= n3)        cnt++;    // If more than two arrays    // have been processed    if(cnt >= 2)        return0;    // If an already computed    // subproblem occurred    if(dp[i][j][k] != -1)        returndp[i][j][k];    intans = 0;    // Explore all the possible pairs    if(i < n1 && j < n2)        // Recursive function call        ans = max(ans,                  getMaxSum(i + 1, j + 1, k,                            arr1, arr2, arr3)                      + arr1[i] * arr2[j]);    if(i < n1 && k < n3)        ans = max(ans,                  getMaxSum(i + 1, j, k + 1,                            arr1, arr2, arr3)                      + arr1[i] * arr3[k]);    if(j < n2 && k < n3)        ans = max(ans,                  getMaxSum(i, j + 1, k + 1,                            arr1, arr2, arr3)                      + arr2[j] * arr3[k]);    // Memoize the maximum    dp[i][j][k] = ans;    // Returning the value    returndp[i][j][k];}// Function to return the maximum sum of// products of pairs possibleintmaxProductSum(intarr1[], intarr2[],                  intarr3[]){    // Initialising the dp array to -1    memset(dp, -1, sizeof(dp));    // Sort the arrays in descending order    sort(arr1, arr1 + n1);    reverse(arr1, arr1 + n1);    sort(arr2, arr2 + n2);    reverse(arr2, arr2 + n2);    sort(arr3, arr3 + n3);    reverse(arr3, arr3 + n3);    returngetMaxSum(0, 0, 0,                     arr1, arr2, arr3);}// Driver Codeintmain(){    n1 = 2;    intarr1[] = { 3, 5 };    n2 = 2;    intarr2[] = { 2, 1 };    n3 = 3;    intarr3[] = { 4, 3, 5 };    cout << maxProductSum(arr1, arr2, arr3);    return0;} | 
Java
| // Java program for above approachimportjava.util.*;importjava.lang.*;classGFG{staticfinalintmaxN = 201; // Variables which represent // the size of the array staticintn1, n2, n3; // Stores the results staticint[][][] dp = newint[maxN][maxN][maxN]; // Function to return the // maximum possible sum staticintgetMaxSum(inti, intj,                      intk, intarr1[],                      intarr2[], intarr3[]) {         // Stores the count of     // arrays processed     intcnt = 0;     if(i >= n1)         cnt++;     if(j >= n2)         cnt++;     if(k >= n3)         cnt++;     // If more than two arrays     // have been processed     if(cnt >= 2)         return0;     // If an already computed     // subproblem occurred     if(dp[i][j][k] != -1)         returndp[i][j][k];     intans = 0;     // Explore all the possible pairs     if(i < n1 && j < n2)         // Recursive function call         ans = Math.max(ans,                        getMaxSum(i + 1, j + 1, k,                                 arr1, arr2, arr3) +                                 arr1[i] * arr2[j]);     if(i < n1 && k < n3)         ans = Math.max(ans,                        getMaxSum(i + 1, j, k + 1,                                  arr1, arr2, arr3) +                                 arr1[i] * arr3[k]);     if(j < n2 && k < n3)         ans = Math.max(ans,                        getMaxSum(i, j + 1, k + 1,                                  arr1, arr2, arr3) +                                 arr2[j] * arr3[k]);     // Memoize the maximum     dp[i][j][k] = ans;     // Returning the value     returndp[i][j][k]; } staticvoidreverse(int[] tmp){    inti, k, t;    intn = tmp.length;            for(i = 0; i < n/ 2; i++)         {             t = tmp[i];             tmp[i] = tmp[n - i - 1];             tmp[n - i - 1] = t;         } }// Function to return the maximum sum of // products of pairs possible staticintmaxProductSum(intarr1[], intarr2[],                          intarr3[]) {         // Initialising the dp array to -1     for(inti = 0; i < dp.length; i++)        for(intj = 0; j < dp[0].length; j++)            for(intk = 0; k < dp[j][0].length; k++)                dp[i][j][k] = -1;    // Sort the arrays in descending order     Arrays.sort(arr1);    reverse(arr1);        Arrays.sort(arr2);    reverse(arr2);        Arrays.sort(arr3);    reverse(arr3);        returngetMaxSum(0, 0, 0,                      arr1, arr2, arr3); } // Driver Codepublicstaticvoidmain (String[] args) {    n1 = 2;     intarr1[] = { 3, 5};         n2 = 2;     intarr2[] = { 2, 1};         n3 = 3;     intarr3[] = { 4, 3, 5};         System.out.println(maxProductSum(arr1, arr2, arr3)); }}// This code is contributed by offbeat | 
Python3
| # Python3 program for # the above approachmaxN =201;# Variables which represent# the size of the arrayn1, n2, n3 =0, 0, 0;# Stores the resultsdp =[[[0fori inrange(maxN)]           forj inrange(maxN)]           forj inrange(maxN)];# Function to return the# maximum possible sumdefgetMaxSum(i, j, k,               arr1, arr2, arr3):      # Stores the count of    # arrays processed    cnt =0;    if(i >=n1):        cnt +=1;    if(j >=n2):        cnt +=1;    if(k >=n3):        cnt +=1;    # If more than two arrays    # have been processed    if(cnt >=2):        return0;    # If an already computed    # subproblem occurred    if(dp[i][j][k] !=-1):        returndp[i][j][k];    ans =0;    # Explore all the possible pairs    if(i < n1 andj < n2):        # Recursive function call        ans =max(ans, getMaxSum(i +1, j +1,                                  k, arr1,                                 arr2, arr3) +                       arr1[i] *arr2[j]);    if(i < n1 andk < n3):        ans =max(ans, getMaxSum(i +1, j,                                  k +1, arr1,                                  arr2, arr3) +                       arr1[i] *arr3[k]);    if(j < n2 andk < n3):        ans =max(ans, getMaxSum(i, j +1,                                  k +1, arr1,                                  arr2, arr3) +                       arr2[j] *arr3[k]);    # Memoize the maximum    dp[i][j][k] =ans;    # Returning the value    returndp[i][j][k];defreverse(tmp):    i, k, t =0, 0, 0;    n =len(tmp);    fori inrange(n //2):        t =tmp[i];        tmp[i] =tmp[n -i -1];        tmp[n -i -1] =t;# Function to return the maximum sum of# products of pairs possibledefmaxProductSum(arr1, arr2, arr3):    # Initialising the dp array to -1    fori inrange(len(dp)):        forj inrange(len(dp[0])):            fork inrange(len(dp[j][0])):                dp[i][j][k] =-1;    # Sort the arrays in descending order    arr1.sort();    reverse(arr1);    arr2.sort();    reverse(arr2);    arr3.sort();    reverse(arr3);    returngetMaxSum(0, 0, 0,                      arr1, arr2, arr3);# Driver Codeif__name__ =='__main__':  n1 =2;  arr1 =[3, 5];  n2 =2;  arr2 =[2, 1];  n3 =3;  arr3 =[4, 3, 5];  print(maxProductSum(arr1, arr2, arr3));# This code is contributed by Rajput-Ji | 
C#
| // C# program for above approach usingSystem; classGFG{ constintmaxN = 201; // Variables which represent // the size of the array staticintn1, n2, n3; // Stores the results staticint[,,] dp = newint[maxN, maxN, maxN]; // Function to return the // maximum possible sum staticintgetMaxSum(inti, intj,                      intk, int[]arr1,                      int[]arr2, int[]arr3) {         // Stores the count of     // arrays processed     intcnt = 0;     if(i >= n1)         cnt++;     if(j >= n2)         cnt++;     if(k >= n3)         cnt++;     // If more than two arrays     // have been processed     if(cnt >= 2)         return0;     // If an already computed     // subproblem occurred     if(dp[i, j, k] != -1)         returndp[i, j, k];     intans = 0;     // Explore all the possible pairs     if(i < n1 && j < n2)         // Recursive function call         ans = Math.Max(ans,                        getMaxSum(i + 1, j + 1, k,                                  arr1, arr2, arr3) +                                  arr1[i] * arr2[j]);     if(i < n1 && k < n3)         ans = Math.Max(ans,                        getMaxSum(i + 1, j, k + 1,                                  arr1, arr2, arr3) +                                  arr1[i] * arr3[k]);     if(j < n2 && k < n3)         ans = Math.Max(ans,                        getMaxSum(i, j + 1, k + 1,                                  arr1, arr2, arr3) +                                  arr2[j] * arr3[k]);         // Memoize the maximum     dp[i, j, k] = ans;     // Returning the value     returndp[i, j, k]; } staticvoidreverse(int[] tmp) {     inti, t;     intn = tmp.Length;     for(i = 0; i < n / 2; i++)     {         t = tmp[i];         tmp[i] = tmp[n - i - 1];         tmp[n - i - 1] = t;     } } // Function to return the maximum sum of // products of pairs possible staticintmaxProductSum(int[]arr1, int[]arr2,                          int[]arr3) {         // Initialising the dp array to -1     for(inti = 0; i < maxN; i++)         for(intj = 0; j < maxN; j++)             for(intk = 0; k < maxN; k++)                 dp[i, j, k] = -1;     // Sort the arrays in descending order     Array.Sort(arr1);     reverse(arr1);         Array.Sort(arr2);     reverse(arr2);         Array.Sort(arr3);     reverse(arr3);         returngetMaxSum(0, 0, 0,                      arr1, arr2, arr3); } // Driver Code publicstaticvoidMain (string[] args) {     n1 = 2;     int[]arr1 = { 3, 5 };         n2 = 2;     int[]arr2 = { 2, 1 };         n3 = 3;     int[]arr3 = { 4, 3, 5 };         Console.Write(maxProductSum(arr1, arr2, arr3)); } } // This code is contributed by rutvik_56 | 
Javascript
| <script>// JavaScript Program to implement// the above approachvarmaxN = 201;// Variables which represent// the size of the arrayvarn1, n2, n3;// Stores the resultsvardp = Array.from(Array(maxN), ()=>Array(maxN));for(vari =0; i<maxN; i++)        for(varj =0; j<maxN; j++)            dp[i][j] = newArray(maxN).fill(-1);// Function to return the// maximum possible sumfunctiongetMaxSum(i, j, k, arr1, arr2, arr3){    // Stores the count of    // arrays processed    varcnt = 0;    if(i >= n1)        cnt++;    if(j >= n2)        cnt++;    if(k >= n3)        cnt++;    // If more than two arrays    // have been processed    if(cnt >= 2)        return0;    // If an already computed    // subproblem occurred    if(dp[i][j][k] != -1)        returndp[i][j][k];    varans = 0;    // Explore all the possible pairs    if(i < n1 && j < n2)        // Recursive function call        ans = Math.max(ans,                  getMaxSum(i + 1, j + 1, k,                            arr1, arr2, arr3)                      + arr1[i] * arr2[j]);    if(i < n1 && k < n3)        ans = Math.max(ans,                  getMaxSum(i + 1, j, k + 1,                            arr1, arr2, arr3)                      + arr1[i] * arr3[k]);    if(j < n2 && k < n3)        ans = Math.max(ans,                  getMaxSum(i, j + 1, k + 1,                            arr1, arr2, arr3)                      + arr2[j] * arr3[k]);    // Memoize the maximum    dp[i][j][k] = ans;    // Returning the value    returndp[i][j][k];}// Function to return the maximum sum of// products of pairs possiblefunctionmaxProductSum(arr1, arr2, arr3){    // Sort the arrays in descending order    arr1.sort();    arr1.reverse();    arr2.sort();    arr2.reverse();    arr3.sort();    arr3.reverse();    returngetMaxSum(0, 0, 0,                     arr1, arr2, arr3);}// Driver Coden1 = 2;vararr1 = [3, 5];n2 = 2;vararr2 = [2, 1];n3 = 3;vararr3 = [4, 3, 5];document.write( maxProductSum(arr1, arr2, arr3));</script> | 
43
Time Complexity: O((N1 * N2 * N3)) 
Auxiliary Space: O(N1 * N2 * N3)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!
 
				 
					


