# 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) = 43

Input: 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 ` `using` `namespace` `std;`   `#define maxN 201`   `// Variables which represent` `// the size of the array` `int` `n1, n2, n3;`   `// Stores the results` `int` `dp[maxN][maxN][maxN];`   `// Function to return the` `// maximum possible sum` `int` `getMaxSum(``int` `i, ``int` `j,` `              ``int` `k, ``int` `arr1[],` `              ``int` `arr2[], ``int` `arr3[])` `{` `    ``// Stores the count of` `    ``// arrays processed` `    ``int` `cnt = 0;`   `    ``if` `(i >= n1)` `        ``cnt++;`   `    ``if` `(j >= n2)` `        ``cnt++;`   `    ``if` `(k >= n3)` `        ``cnt++;`   `    ``// If more than two arrays` `    ``// have been processed` `    ``if` `(cnt >= 2)` `        ``return` `0;`   `    ``// If an already computed` `    ``// subproblem occurred` `    ``if` `(dp[i][j][k] != -1)` `        ``return` `dp[i][j][k];`   `    ``int` `ans = 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` `    ``return` `dp[i][j][k];` `}`   `// Function to return the maximum sum of` `// products of pairs possible` `int` `maxProductSum(``int` `arr1[], ``int` `arr2[],` `                  ``int` `arr3[])` `{` `    ``// 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);`   `    ``return` `getMaxSum(0, 0, 0,` `                     ``arr1, arr2, arr3);` `}`   `// Driver Code` `int` `main()` `{` `    ``n1 = 2;` `    ``int` `arr1[] = { 3, 5 };`   `    ``n2 = 2;` `    ``int` `arr2[] = { 2, 1 };`   `    ``n3 = 3;` `    ``int` `arr3[] = { 4, 3, 5 };`   `    ``cout << maxProductSum(arr1, arr2, arr3);`   `    ``return` `0;` `}`

## Java

 `// Java program for above approach` `import` `java.util.*;` `import` `java.lang.*;`   `class` `GFG{`   `static` `final` `int` `maxN = ``201``; `   `// Variables which represent ` `// the size of the array ` `static` `int` `n1, n2, n3; `   `// Stores the results ` `static` `int``[][][] dp = ``new` `int``[maxN][maxN][maxN]; `   `// Function to return the ` `// maximum possible sum ` `static` `int` `getMaxSum(``int` `i, ``int` `j, ` `                     ``int` `k, ``int` `arr1[], ` `                     ``int` `arr2[], ``int` `arr3[]) ` `{ ` `    `  `    ``// Stores the count of ` `    ``// arrays processed ` `    ``int` `cnt = ``0``; `   `    ``if` `(i >= n1) ` `        ``cnt++; `   `    ``if` `(j >= n2) ` `        ``cnt++; `   `    ``if` `(k >= n3) ` `        ``cnt++; `   `    ``// If more than two arrays ` `    ``// have been processed ` `    ``if` `(cnt >= ``2``) ` `        ``return` `0``; `   `    ``// If an already computed ` `    ``// subproblem occurred ` `    ``if` `(dp[i][j][k] != -``1``) ` `        ``return` `dp[i][j][k]; `   `    ``int` `ans = ``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 ` `    ``return` `dp[i][j][k]; ` `} `   `static` `void` `reverse(``int``[] tmp)` `{` `    ``int` `i, k, t;` `    ``int` `n = 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 ` `static` `int` `maxProductSum(``int` `arr1[], ``int` `arr2[], ` `                         ``int` `arr3[]) ` `{ ` `    `  `    ``// Initialising the dp array to -1 ` `    ``for``(``int` `i = ``0``; i < dp.length; i++)` `        ``for``(``int` `j = ``0``; j < dp[``0``].length; j++)` `            ``for``(``int` `k = ``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);` `    `  `    ``return` `getMaxSum(``0``, ``0``, ``0``, ` `                     ``arr1, arr2, arr3); ` `} `   `// Driver Code` `public` `static` `void` `main (String[] args) ` `{` `    ``n1 = ``2``; ` `    ``int` `arr1[] = { ``3``, ``5` `}; ` `    `  `    ``n2 = ``2``; ` `    ``int` `arr2[] = { ``2``, ``1` `}; ` `    `  `    ``n3 = ``3``; ` `    ``int` `arr3[] = { ``4``, ``3``, ``5` `}; ` `    `  `    ``System.out.println(maxProductSum(arr1, arr2, arr3)); ` `}` `}`   `// This code is contributed by offbeat`

## Python3

 `# Python3 program for ` `# the above approach` `maxN ``=` `201``;`   `# Variables which represent` `# the size of the array` `n1, n2, n3 ``=` `0``, ``0``, ``0``;`   `# Stores the results` `dp ``=` `[[[``0` `for` `i ``in` `range``(maxN)] ` `          ``for` `j ``in` `range``(maxN)] ` `          ``for` `j ``in` `range``(maxN)];`   `# Function to return the` `# maximum possible sum` `def` `getMaxSum(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``):` `        ``return` `0``;`   `    ``# If an already computed` `    ``# subproblem occurred` `    ``if` `(dp[i][j][k] !``=` `-``1``):` `        ``return` `dp[i][j][k];`   `    ``ans ``=` `0``;`   `    ``# Explore all the possible pairs` `    ``if` `(i < n1 ``and` `j < n2):`   `        ``# Recursive function call` `        ``ans ``=` `max``(ans, getMaxSum(i ``+` `1``, j ``+` `1``, ` `                                 ``k, arr1,` `                                 ``arr2, arr3) ``+` `                       ``arr1[i] ``*` `arr2[j]);`   `    ``if` `(i < n1 ``and` `k < n3):` `        ``ans ``=` `max``(ans, getMaxSum(i ``+` `1``, j, ` `                                 ``k ``+` `1``, arr1, ` `                                 ``arr2, arr3) ``+` `                       ``arr1[i] ``*` `arr3[k]);`   `    ``if` `(j < n2 ``and` `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` `    ``return` `dp[i][j][k];`     `def` `reverse(tmp):` `    ``i, k, t ``=` `0``, ``0``, ``0``;` `    ``n ``=` `len``(tmp);`   `    ``for` `i ``in` `range``(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 possible` `def` `maxProductSum(arr1, arr2, arr3):` `    ``# Initialising the dp array to -1` `    ``for` `i ``in` `range``(``len``(dp)):` `        ``for` `j ``in` `range``(``len``(dp[``0``])):` `            ``for` `k ``in` `range``(``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);`   `    ``return` `getMaxSum(``0``, ``0``, ``0``, ` `                     ``arr1, arr2, arr3);`   `# Driver Code` `if` `__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 ` `using` `System; `   `class` `GFG{ `   `const` `int` `maxN = 201; `   `// Variables which represent ` `// the size of the array ` `static` `int` `n1, n2, n3; `   `// Stores the results ` `static` `int``[,,] dp = ``new` `int``[maxN, maxN, maxN]; `   `// Function to return the ` `// maximum possible sum ` `static` `int` `getMaxSum(``int` `i, ``int` `j, ` `                     ``int` `k, ``int` `[]arr1, ` `                     ``int` `[]arr2, ``int` `[]arr3) ` `{ ` `    `  `    ``// Stores the count of ` `    ``// arrays processed ` `    ``int` `cnt = 0; `   `    ``if` `(i >= n1) ` `        ``cnt++; `   `    ``if` `(j >= n2) ` `        ``cnt++; `   `    ``if` `(k >= n3) ` `        ``cnt++; `   `    ``// If more than two arrays ` `    ``// have been processed ` `    ``if` `(cnt >= 2) ` `        ``return` `0; `   `    ``// If an already computed ` `    ``// subproblem occurred ` `    ``if` `(dp[i, j, k] != -1) ` `        ``return` `dp[i, j, k]; `   `    ``int` `ans = 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 ` `    ``return` `dp[i, j, k]; ` `} `   `static` `void` `reverse(``int``[] tmp) ` `{ ` `    ``int` `i, t; ` `    ``int` `n = 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 ` `static` `int` `maxProductSum(``int` `[]arr1, ``int` `[]arr2, ` `                         ``int` `[]arr3) ` `{ ` `    `  `    ``// Initialising the dp array to -1 ` `    ``for``(``int` `i = 0; i < maxN; i++) ` `        ``for``(``int` `j = 0; j < maxN; j++) ` `            ``for``(``int` `k = 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); ` `    `  `    ``return` `getMaxSum(0, 0, 0, ` `                     ``arr1, arr2, arr3); ` `} `   `// Driver Code ` `public` `static` `void` `Main (``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`

Output:

```43

```

Time Complexity: O((N1 * N2 * N3))
Auxiliary Space: O(N1 * N2 * N3)

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 : offbeat, rutvik_56, Rajput-Ji