Find Maximum dot product of two arrays with insertion of 0’s
Given two arrays of positive integers of size m and n where m > n. We need to maximize the dot product by inserting zeros in the second array but we cannot disturb the order of elements.
Examples:
Input : A[] = {2, 3 , 1, 7, 8} , B[] = {3, 6, 7}
Output : 107
Explanation : We get maximum dot product after inserting 0 at first and third positions in second array.
Maximum Dot Product : = A[i] * B[j]
2*0 + 3*3 + 1*0 + 7*6 + 8*7 = 107
Input : A[] = {1, 2, 3, 6, 1, 4}, B[] = {4, 5, 1}
Output : 46
Asked in: Directi Interview
Another way to look at this problem is, for every pair of elements element A[i] and B[j] where j >= i , we have two choices:
- We multiply A[i] and B[j] and add to the product (We include A[i]).
- We exclude A[i] from the product (In other words, we insert 0 at the current position in B[])
The idea is to use Dynamic programming .
1) Given Array A[] of size 'm' and B[] of size 'n'
2) Create 2D matrix 'DP[n + 1][m + 1]' initialize it
with '0'
3) Run loop outer loop for i = 1 to n
Inner loop j = i to m
// Two cases arise
// 1) Include A[j]
// 2) Exclude A[j] (insert 0 in B[])
dp[i][j] = max(dp[i-1][j-1] + A[j-1] * B[i -1],
dp[i][j-1])
// Last return maximum dot product that is
return dp[n][m]
Below is the implementation of the above idea.
C++
#include<bits/stdc++.h>
using namespace std;
long long int MaxDotProduct( int A[], int B[],
int m, int n)
{
long long int dp[n+1][m+1];
memset (dp, 0, sizeof (dp));
for ( int i=1; i<=n; i++)
for ( int j=i; j<=m; j++)
dp[i][j] = max((dp[i-1][j-1] + (A[j-1]*B[i-1])) ,
dp[i][j-1]);
return dp[n][m] ;
}
int main()
{
int A[] = { 2, 3 , 1, 7, 8 } ;
int B[] = { 3, 6, 7 } ;
int m = sizeof (A)/ sizeof (A[0]);
int n = sizeof (B)/ sizeof (B[0]);
cout << MaxDotProduct(A, B, m, n);
return 0;
}
|
Java
import java.util.*;
class GFG
{
static int MaxDotProduct( int A[], int B[], int m, int n)
{
int dp[][] = new int [n + 1 ][m + 1 ];
for ( int [] row : dp)
Arrays.fill(row, 0 );
for ( int i = 1 ; i <= n; i++)
for ( int j = i; j <= m; j++)
dp[i][j] =
Math.max((dp[i - 1 ][j - 1 ] +
(A[j - 1 ] * B[i - 1 ])), dp[i][j - 1 ]);
return dp[n][m];
}
public static void main(String[] args) {
int A[] = { 2 , 3 , 1 , 7 , 8 };
int B[] = { 3 , 6 , 7 };
int m = A.length;
int n = B.length;
System.out.print(MaxDotProduct(A, B, m, n));
}
}
|
Python3
def MaxDotProduct(A, B, m, n):
dp = [[ 0 for i in range (m + 1 )]
for j in range (n + 1 )]
for i in range ( 1 , n + 1 , 1 ):
for j in range (i, m + 1 , 1 ):
dp[i][j] = max ((dp[i - 1 ][j - 1 ] +
(A[j - 1 ] * B[i - 1 ])) ,
dp[i][j - 1 ])
return dp[n][m]
if __name__ = = '__main__' :
A = [ 2 , 3 , 1 , 7 , 8 ]
B = [ 3 , 6 , 7 ]
m = len (A)
n = len (B)
print (MaxDotProduct(A, B, m, n))
|
C#
using System;
public class GFG{
static int MaxDotProduct( int []A, int []B, int m, int n)
{
int [,]dp = new int [n + 1,m + 1];
for ( int i = 1; i <= n; i++)
for ( int j = i; j <= m; j++)
dp[i,j] =
Math.Max((dp[i - 1,j - 1] +
(A[j - 1] * B[i - 1])), dp[i,j - 1]);
return dp[n,m];
}
public static void Main() {
int []A = {2, 3, 1, 7, 8};
int []B = {3, 6, 7};
int m = A.Length;
int n = B.Length;
Console.Write(MaxDotProduct(A, B, m, n));
}
}
|
Javascript
<script>
function MaxDotProduct(A, B, m, n)
{
let dp = new Array(n + 1);
for (let i = 0; i < (n + 1); i++)
{
dp[i] = new Array(m+1);
for (let j = 0; j < m + 1; j++)
{
dp[i][j] = 0;
}
}
for (let i = 1; i <= n; i++)
for (let j = i; j <= m; j++)
dp[i][j] =
Math.max((dp[i - 1][j - 1] +
(A[j - 1] * B[i - 1])), dp[i][j - 1]);
return dp[n][m];
}
let A = [2, 3, 1, 7, 8];
let B = [3, 6, 7];
let m = A.length;
let n = B.length;
document.write(MaxDotProduct(A, B, m, n));
</script>
|
Time Complexity : O(n*m)
Auxiliary Space: O(n*m)
Efficient approach : Space optimization
In previous approach the current value dp[i][j] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.
Implementation steps:
- Create an array dp to store the maximum dot product values.
- Initialize all elements of dp to 0.
- Iterate over the A array and process each element.
- For each element in A, iterate over the B array in reverse order and process each element.
- Update dp[j] with the maximum value between the current dp[j] and dp[j – 1] + (A[i – 1] * B[j – 1]).
- After the loops, dp[n] will represent the maximum dot product achievable.
- Return dp[n] as the result.
Implementation:
C++
#include<bits/stdc++.h>
using namespace std;
long long int MaxDotProduct( int A[], int B[], int m, int n)
{
long long int dp[n + 1];
memset (dp, 0, sizeof (dp));
for ( int i = 1; i <= m; i++) {
for ( int j = n; j >= 1; j--) {
dp[j] = max(dp[j], dp[j - 1] + (A[i - 1] * B[j - 1]));
}
}
return dp[n];
}
int main()
{
int A[] = { 2, 3, 1, 7, 8 };
int B[] = { 3, 6, 7 };
int m = sizeof (A) / sizeof (A[0]);
int n = sizeof (B) / sizeof (B[0]);
cout << MaxDotProduct(A, B, m, n);
return 0;
}
|
Java
import java.util.Arrays;
public class GFG {
static long MaxDotProduct( int [] A, int [] B, int m,
int n)
{
long [] dp = new long [n + 1 ];
Arrays.fill(dp,
0 );
for ( int i = 1 ; i <= m; i++) {
for ( int j = n; j >= 1 ; j--) {
dp[j] = Math.max(
dp[j],
dp[j - 1 ] + (A[i - 1 ] * B[j - 1 ]));
}
}
return dp[n];
}
public static void main(String[] args)
{
int [] A = { 2 , 3 , 1 , 7 , 8 };
int [] B = { 3 , 6 , 7 };
int m = A.length;
int n = B.length;
System.out.println(MaxDotProduct(A, B, m, n));
}
}
|
Python3
def MaxDotProduct(A, B, m, n):
dp = [ 0 ] * (n + 1 )
for i in range ( 1 , m + 1 ):
for j in range (n, 0 , - 1 ):
dp[j] = max (dp[j], dp[j - 1 ] + (A[i - 1 ] * B[j - 1 ]))
return dp[n]
A = [ 2 , 3 , 1 , 7 , 8 ]
B = [ 3 , 6 , 7 ]
m = len (A)
n = len (B)
print (MaxDotProduct(A, B, m, n))
|
C#
using System;
class GFG {
static long MaxDotProduct( int [] A, int [] B, int m,
int n)
{
long [] dp = new long [n + 1];
for ( int i = 1; i <= m; i++) {
for ( int j = n; j >= 1; j--) {
dp[j] = Math.Max(
dp[j],
dp[j - 1] + (A[i - 1] * B[j - 1]));
}
}
return dp[n];
}
static void Main()
{
int [] A = { 2, 3, 1, 7, 8 };
int [] B = { 3, 6, 7 };
int m = A.Length;
int n = B.Length;
Console.WriteLine(MaxDotProduct(A, B, m, n));
}
}
|
Javascript
function MaxDotProduct(A, B, m, n) {
const dp = new Array(n + 1).fill(0);
for (let i = 1; i <= m; i++) {
for (let j = n; j >= 1; j--) {
dp[j] = Math.max(dp[j], dp[j - 1] + (A[i - 1] * B[j - 1]));
}
}
return dp[n];
}
const A = [2, 3, 1, 7, 8];
const B = [3, 6, 7];
const m = A.length;
const n = B.length;
console.log(MaxDotProduct(A, B, m, n));
|
Time Complexity : O(n*m)
Auxiliary Space: O(n)
Last Updated :
13 Sep, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...