Maximize count of indices with same element by pairing rows from given Matrices
Last Updated :
09 Feb, 2023
Given two 2D binary arrays, a[][] and b[][] both of size M*N, the task is to pair each row in the array a[][] with any row in the array b[][] such that the total score can be maximized and the score for each pair is calculated as the total indexes at which values of both rows are identical.
Note: Each row of the array b[][] can only be paired with a single row of vector a[][].
Examples:
Input: a[][] = {{1, 1, 0}, {1, 0, 1}, {0, 0, 1}}, b[][] = {{1, 0, 0}, {0, 0, 1}, {1, 1, 0}}
Output: 8
Explanation:
Consider the pairing of rows in the following order, to maximize the total score obtained:
- Row 0 of a[][] paired with row 2 of b[][] has the score of 3.
- Row 1 of a[][] paired with row 0 of b[][] with score of 2.
- Row 2 of a[][] paired with row 1 of b[][] with score of 3.
Therefore, the sum of scores obtained is 3 + 2 + 3 = 8.
Input: a[][] = {{0, 0}, {0, 0}, {0, 0}}, b[][] = {{1, 1}, {1, 1}, {1, 1}}
Output: 0
Naive Approach: The simplest approach to solve the given problem is to generate all possible permutations of the rows of the arrays a[][] and for each permutation of the array a[][], find the sum of scores of each corresponding pair, and if it’s greater than the current answer, update the answer to the value of the current sum of scores. After checking for all the pairs, print the maximum score obtained.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
void maxScoreSum(vector<vector< int > >& a,
vector<vector< int > >& b)
{
int maxSum = 0;
vector< int > pos;
for ( int i = 0; i < a.size(); i++) {
pos.push_back(i);
}
do {
int curSum = 0;
for ( int i = 0; i < a.size(); i++) {
for ( int j = 0;
j < a[pos[i]].size(); j++) {
curSum += (a[pos[i]][j] == b[i][j]);
maxSum = max(maxSum, curSum);
}
}
} while (next_permutation(pos.begin(), pos.end()));
cout << maxSum;
}
int main()
{
int N = 3, M = 3;
vector<vector< int > > a
= { { 1, 1, 0 }, { 1, 0, 1 }, { 0, 0, 1 } };
vector<vector< int > > b
= { { 1, 0, 0 }, { 0, 0, 1 }, { 1, 1, 0 } };
maxScoreSum(a, b);
return 0;
}
|
Java
import java.util.*;
class GFG {
public static List<List<Integer> > perms
= new ArrayList<>();
public static void
generatePermutations( int mask, int ind, int N,
List<Integer> current)
{
if (ind == N) {
List<Integer> temp = new ArrayList<>(current);
perms.add(temp);
return ;
}
for ( int i = 0 ; i < N; i++) {
if (((mask >> i) & 1 ) == 0 ) {
current.add(i);
generatePermutations(mask | ( 1 << i),
ind + 1 , N, current);
current.remove(current.size() - 1 );
}
}
}
public static void maxScoreSum(List<List<Integer> > a,
List<List<Integer> > b)
{
int maxSum = 0 ;
generatePermutations( 0 , 0 , a.size(),
new ArrayList<Integer>());
for ( int ind = 0 ; ind < perms.size(); ind++) {
List<Integer> pos = perms.get(ind);
int curSum = 0 ;
for ( int i = 0 ; i < a.size(); i++) {
for ( int j = 0 ;
j < a.get(pos.get(i)).size(); j++) {
curSum += (a.get(pos.get(i)).get(j)
== b.get(i).get(j)
? 1
: 0 );
maxSum = Math.max(maxSum, curSum);
}
}
}
System.out.println(maxSum);
}
public static void main(String[] args)
{
List<List<Integer> > a = new ArrayList<>();
a.add(Arrays.asList( 1 , 1 , 0 ));
a.add(Arrays.asList( 1 , 0 , 1 ));
a.add(Arrays.asList( 0 , 0 , 1 ));
List<List<Integer> > b = new ArrayList<>();
b.add(Arrays.asList( 1 , 0 , 0 ));
b.add(Arrays.asList( 0 , 0 , 1 ));
b.add(Arrays.asList( 1 , 1 , 0 ));
maxScoreSum(a, b);
}
}
|
Python3
def next_permutation(array):
i = len (array) - 1
while (i > 0 and array[i - 1 ] > = array[i]):
i - = 1
if (i < = 0 ):
return False
j = len (array) - 1
while (array[j] < = array[i - 1 ]):
j - = 1
temp = array[i - 1 ]
array[i - 1 ] = array[j]
array[j] = temp
j = len (array) - 1
while (i < j):
temp = array[i];
array[i] = array[j];
array[j] = temp;
i + = 1
j - = 1
return array
def maxScoreSum(a, b):
maxSum = 0
pos = []
for i in range ( len (a)):
pos.append(i)
while ( True ):
curSum = 0
for i in range ( len (a)):
for j in range ( len (a[pos[i]])):
curSum + = (a[pos[i]][j] = = b[i][j])
maxSum = max (maxSum, curSum)
if (next_permutation(pos) = = False ):
break
print (maxSum)
N, M = 3 , 3
a = [[ 1 , 1 , 0 ], [ 1 , 0 , 1 ], [ 0 , 0 , 1 ]]
b = [[ 1 , 0 , 0 ], [ 0 , 0 , 1 ], [ 1 , 1 , 0 ]]
maxScoreSum(a, b)
|
C#
using System;
using System.Collections.Generic;
class GFG
{
public static List<List< int >> perms = new List<List< int >>();
public static void generate_permuatation( int mask, int ind, int N, List< int > current){
if (ind == N){
List< int > temp = new List< int >(current);
perms.Add(temp);
return ;
}
for ( int i = 0 ; i < N ; i++){
if (((mask >> i) & 1) == 0){
current.Add(i);
generate_permuatation(mask | (1 << i), ind + 1, N, current);
current.RemoveAt(current.Count-1);
}
}
}
public static void maxScoreSum(List<List< int >> a, List<List< int >> b)
{
int maxSum = 0;
generate_permuatation(0, 0, a.Count, new List< int >());
for ( int ind = 0 ; ind < perms.Count ; ind++){
List< int > pos = perms[ind];
int curSum = 0;
for ( int i = 0; i < a.Count ; i++) {
for ( int j = 0 ; j < a[pos[i]].Count ; j++) {
curSum += (a[pos[i]][j] == b[i][j] ? 1 : 0);
maxSum = Math.Max(maxSum, curSum);
}
}
}
Console.Write(maxSum);
}
public static void Main( string [] args){
List<List< int >> a = new List<List< int >>{
new List< int >{ 1, 1, 0 },
new List< int >{ 1, 0, 1 },
new List< int >{ 0, 0, 1 }
};
List<List< int >> b = new List<List< int >>{
new List< int >{ 1, 0, 0 },
new List< int >{ 0, 0, 1 },
new List< int >{ 1, 1, 0 }
};
maxScoreSum(a, b);
}
}
|
Javascript
<script>
function next_permutation(array) {
var i = array.length - 1;
while (i > 0 && array[i - 1] >= array[i]) {
i--;
}
if (i <= 0) {
return false ;
}
var j = array.length - 1;
while (array[j] <= array[i - 1]) {
j--;
}
var temp = array[i - 1];
array[i - 1] = array[j];
array[j] = temp;
j = array.length - 1;
while (i < j) {
temp = array[i];
array[i] = array[j];
array[j] = temp;
i++;
j--;
}
return array;
}
function maxScoreSum(a, b) {
let maxSum = 0;
let pos = [];
for (let i = 0; i < a.length; i++) {
pos.push(i);
}
do {
let curSum = 0;
for (let i = 0; i < a.length; i++) {
for (let j = 0;
j < a[pos[i]].length; j++) {
curSum += (a[pos[i]][j] == b[i][j]);
maxSum = Math.max(maxSum, curSum);
}
}
} while (next_permutation(pos));
document.write(maxSum);
}
let N = 3, M = 3;
let a
= [[1, 1, 0], [1, 0, 1], [0, 0, 1]];
let b
= [[1, 0, 0], [0, 0, 1], [1, 1, 0]];
maxScoreSum(a, b);
</script>
|
Time Complexity: O(N*M*M!), where M! are the number of permutations and N*M for calculating the score of each pair.
Auxiliary Space: O(M)
Efficient Approach: The above approach can also be optimized using the concept of Bitmasking, The idea is for each row in vector a[][], try all rows in vector b[][] that haven’t been chosen before. Use a bitmask to represent already chosen rows of vector b[][]. To avoid re-computing the same subproblem, memoize the result for each bitmask. Follow the steps below to solve the problem:
- Initialize the variables row as 0, mask as (2M – 1).
- Initialize the vector dp[] of size mask + 1 with values -1.
- If row is greater than equal to a.size() then return 0 and if dp[mask] is not equal to -1 then return dp[mask].
- Initialize the variable ans as 0 to store the answer.
- Iterate over the range [0, a.size()) using the variable i and perform the following tasks:
- If the bitwise AND of mask and 2i is true then initialize the variable newMask as mask^(1<<i) and curSum as 0.
- Iterate over the range [0, a[i].size()) using the variable j and if a[row][j] equals b[i][j] then increase the value of curSum by 1.
- Set the value of ans as the maximum of ans or curSum + maxScoreSum(a, b, row+1, newmask, dp) recursively.
- After performing the above steps, set the value of dp[mask] as ans and return the value of ans as the answer.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int maxScoreSum(vector<vector< int > >& a,
vector<vector< int > >& b,
int row, int mask,
vector< int >& dp)
{
if (row >= a.size()) {
return 0;
}
if (dp[mask] != -1) {
return dp[mask];
}
int ans = 0;
for ( int i = 0; i < a.size(); i++) {
if (mask & (1 << i)) {
int newMask = mask ^ (1 << i);
int curSum = 0;
for ( int j = 0; j < a[i].size(); j++) {
if (a[row][j] == b[i][j]) {
curSum++;
}
}
ans = max(
ans, curSum
+ maxScoreSum(
a, b, row + 1,
newMask, dp));
}
}
return dp[mask] = ans;
}
int maxScoreSumUtil(vector<vector< int > >& a,
vector<vector< int > >& b,
int N, int M)
{
int row = 0;
int mask = pow (2, M) - 1;
vector< int > dp(mask + 1, -1);
return maxScoreSum(a, b, row, mask, dp);
}
int main()
{
int N = 3, M = 3;
vector<vector< int > > a
= { { 1, 1, 0 }, { 1, 0, 1 }, { 0, 0, 1 } };
vector<vector< int > > b
= { { 1, 0, 0 }, { 0, 0, 1 }, { 1, 1, 0 } };
cout << maxScoreSumUtil(a, b, N, M);
return 0;
}
|
Java
import java.util.ArrayList;
import java.util.List;
class GFG {
public static int maxScoreSum(List<List<Integer> > a,
List<List<Integer> > b,
int row, int mask,
int [] dp)
{
if (row >= a.size()) {
return 0 ;
}
if (dp[mask] != - 1 ) {
return dp[mask];
}
int ans = 0 ;
for ( int i = 0 ; i < a.size(); i++) {
if ((mask & ( 1 << i)) > 0 ) {
int newMask = mask ^ ( 1 << i);
int curSum = 0 ;
for ( int j = 0 ; j < a.get(i).size(); j++) {
if (a.get(row).get(j)
== b.get(i).get(j)) {
curSum++;
}
}
ans = Math.max(
ans, curSum
+ maxScoreSum(a, b, row + 1 ,
newMask, dp));
}
}
return dp[mask] = ans;
}
public static int
maxScoreSumUtil(List<List<Integer> > a,
List<List<Integer> > b, int N, int M)
{
int row = 0 ;
int mask = ( int )Math.pow( 2 , M) - 1 ;
int [] dp = new int [ 1 << M];
for ( int i = 0 ; i <= mask; i++) {
dp[i] = - 1 ;
}
return maxScoreSum(a, b, row, mask, dp);
}
public static void main(String[] args)
{
int N = 3 ;
int M = 3 ;
List<List<Integer> > a
= new ArrayList<List<Integer> >() {
{
add( new ArrayList<Integer>() {
{
add( 1 );
add( 1 );
add( 0 );
}
});
add( new ArrayList<Integer>() {
{
add( 1 );
add( 0 );
add( 1 );
}
});
add( new ArrayList<Integer>() {
{
add( 0 );
add( 0 );
add( 1 );
}
});
}
};
List<List<Integer> > b
= new ArrayList<List<Integer> >() {
{
add( new ArrayList<Integer>() {
{
add( 1 );
add( 0 );
add( 0 );
}
});
add( new ArrayList<Integer>() {
{
add( 0 );
add( 0 );
add( 1 );
}
});
add( new ArrayList<Integer>() {
{
add( 1 );
add( 1 );
add( 0 );
}
});
}
};
System.out.println(maxScoreSumUtil(a, b, N, M));
}
}
|
Python3
def maxScoreSum(a, b, row, mask, dp):
if (row > = len (a)):
return 0
if (dp[mask] ! = - 1 ):
return dp[mask]
ans = 0
for i in range ( len (a)):
if (mask & ( 1 << i)):
newMask = mask ^ ( 1 << i)
curSum = 0
for j in range ( len (a[i])):
if (a[row][j] = = b[i][j]):
curSum + = 1
ans = max (
ans, curSum
+ maxScoreSum(
a, b, row + 1 ,
newMask, dp))
dp[mask] = ans
return dp[mask]
def maxScoreSumUtil(a,
b,
N, M):
row = 0
mask = pow ( 2 , M) - 1
dp = [ - 1 ] * (mask + 1 )
return maxScoreSum(a, b, row, mask, dp)
if __name__ = = "__main__" :
N = 3
M = 3
a = [[ 1 , 1 , 0 ], [ 1 , 0 , 1 ], [ 0 , 0 , 1 ]]
b = [[ 1 , 0 , 0 ], [ 0 , 0 , 1 ], [ 1 , 1 , 0 ]]
print (maxScoreSumUtil(a, b, N, M))
|
C#
using System;
using System.Collections.Generic;
class GFG
{
public static int maxScoreSum(List<List< int >> a, List<List< int >> b, int row, int mask, List< int > dp)
{
if (row >= a.Count){
return 0;
}
if (dp[mask] != -1){
return dp[mask];
}
int ans = 0;
for ( int i = 0 ; i < a.Count ; i++) {
if ((mask & (1 << i)) > 0){
int newMask = mask ^ (1 << i);
int curSum = 0;
for ( int j = 0; j < a[i].Count ; j++) {
if (a[row][j] == b[i][j]) {
curSum++;
}
}
ans = Math.Max(ans, curSum + maxScoreSum(a, b, row + 1, newMask, dp));
}
}
return dp[mask] = ans;
}
public static int maxScoreSumUtil(List<List< int >> a, List<List< int >> b, int N, int M)
{
int row = 0;
int mask = ( int )Math.Pow(2, M) - 1;
List< int > dp = new List< int >();
for ( int i = 0 ; i <= mask ; i++){
dp.Add(-1);
}
return maxScoreSum(a, b, row, mask, dp);
}
public static void Main( string [] args){
int N = 3;
int M = 3;
List<List< int >> a = new List<List< int >>{
new List< int >{ 1, 1, 0 },
new List< int >{ 1, 0, 1 },
new List< int >{ 0, 0, 1 }
};
List<List< int >> b = new List<List< int >>{
new List< int >{ 1, 0, 0 },
new List< int >{ 0, 0, 1 },
new List< int >{ 1, 1, 0 }
};
Console.Write(maxScoreSumUtil(a, b, N, M));
}
}
|
Javascript
<script>
function maxScoreSum(a, b, row, mask, dp){
if (row >= a.length)
return 0
if (dp[mask] != -1)
return dp[mask]
let ans = 0
for (let i=0;i<a.length;i++){
if (mask & (1 << i)){
newMask = mask ^ (1 << i)
curSum = 0
for (let j=0;j<a[i].length;j++){
if (a[row][j] == b[i][j])
curSum += 1
}
ans = Math.max(ans, curSum + maxScoreSum(a, b, row + 1,newMask, dp))
}
}
dp[mask] = ans
return dp[mask]
}
function maxScoreSumUtil(a,b,N, M){
let row = 0
let mask = Math.pow(2, M) - 1
let dp = new Array(mask + 1).fill(-1)
return maxScoreSum(a, b, row, mask, dp)
}
let N = 3
let M = 3
let a = [[1, 1, 0], [1, 0, 1], [0, 0, 1]]
let b = [[1, 0, 0], [0, 0, 1], [1, 1, 0]]
document.write(maxScoreSumUtil(a, b, N, M), "</br>" )
</script>
|
Time Complexity: O(2M*M*N)
Auxiliary Space: O(2M)
Share your thoughts in the comments
Please Login to comment...