通过配对给定矩阵中的行来最大化具有相同元素的索引计数
给定两个大小为M*N的二维二进制数组a[][]和b[][] ,任务是将数组a[][]中的每一行与数组b[][]中的任意行配对 这样总分可以最大化,并且每对的分数被计算为两行值相同的总索引。
注意:数组b[][]的每一行只能与向量的单行配对 一个[][] 。
例子:
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
朴素方法:解决给定问题的最简单方法是生成数组 a[][] 的行的所有可能排列,并且对于数组 a [ ][]的每个排列,找到每个对应对的分数总和,如果它大于当前答案,则将答案更新为当前分数总和的值。检查所有对后,打印获得的最高分数。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum score
void maxScoreSum(vector >& a,
vector >& b)
{
// Stores the maximum sum of scores
int maxSum = 0;
vector pos;
for (int i = 0; i < a.size(); i++) {
pos.push_back(i);
}
// For each permutation of pos vector
// calculate the score
do {
int curSum = 0;
for (int i = 0; i < a.size(); i++) {
for (int j = 0;
j < a[pos[i]].size(); j++) {
// If values at current indexes
// are same then increment the
// current score
curSum += (a[pos[i]][j] == b[i][j]);
maxSum = max(maxSum, curSum);
}
}
} while (next_permutation(pos.begin(), pos.end()));
// Print the maximum score
cout << maxSum;
}
// Driver Code
int main()
{
int N = 3, M = 3;
vector > a
= { { 1, 1, 0 }, { 1, 0, 1 }, { 0, 0, 1 } };
vector > b
= { { 1, 0, 0 }, { 0, 0, 1 }, { 1, 1, 0 } };
maxScoreSum(a, b);
return 0;
}
Javascript
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum defined
// score
int maxScoreSum(vector >& a,
vector >& b,
int row, int mask,
vector& dp)
{
// If all students are assigned
if (row >= a.size()) {
return 0;
}
if (dp[mask] != -1) {
return dp[mask];
}
int ans = 0;
for (int i = 0; i < a.size(); i++) {
// Check if row is not paired yet
if (mask & (1 << i)) {
int newMask = mask ^ (1 << i);
int curSum = 0;
// Check for all indexes
for (int j = 0; j < a[i].size(); j++) {
// If values at current indexes
// are same increase curSum
if (a[row][j] == b[i][j]) {
curSum++;
}
}
// Further recursive call
ans = max(
ans, curSum
+ maxScoreSum(
a, b, row + 1,
newMask, dp));
}
}
// Store the ans for current
// mask and return
return dp[mask] = ans;
}
// Utility function to find the maximum
// defined score
int maxScoreSumUtil(vector >& a,
vector >& b,
int N, int M)
{
int row = 0;
// Create a mask with all set bits
// 1 -> row is not paired yet
// 0 -> row is already paired
int mask = pow(2, M) - 1;
// Initialise dp array with -1
vector dp(mask + 1, -1);
return maxScoreSum(a, b, row, mask, dp);
}
// Driver Code
int main()
{
int N = 3, M = 3;
vector > a
= { { 1, 1, 0 }, { 1, 0, 1 }, { 0, 0, 1 } };
vector > b
= { { 1, 0, 0 }, { 0, 0, 1 }, { 1, 1, 0 } };
cout << maxScoreSumUtil(a, b, N, M);
return 0;
}
Python3
# Python 3 program for the above approach
# Function to find the maximum defined
# score
def maxScoreSum(a, b, row, mask, dp):
# If all students are assigned
if (row >= len(a)):
return 0
if (dp[mask] != -1):
return dp[mask]
ans = 0
for i in range(len(a)):
# Check if row is not paired yet
if (mask & (1 << i)):
newMask = mask ^ (1 << i)
curSum = 0
# Check for all indexes
for j in range(len(a[i])):
# If values at current indexes
# are same increase curSum
if (a[row][j] == b[i][j]):
curSum += 1
# Further recursive call
ans = max(
ans, curSum
+ maxScoreSum(
a, b, row + 1,
newMask, dp))
# Store the ans for current
# mask and return
dp[mask] = ans
return dp[mask]
# Utility function to find the maximum
# defined score
def maxScoreSumUtil(a,
b,
N, M):
row = 0
# Create a mask with all set bits
# 1 -> row is not paired yet
# 0 -> row is already paired
mask = pow(2, M) - 1
# Initialise dp array with -1
dp = [-1]*(mask + 1)
return maxScoreSum(a, b, row, mask, dp)
# Driver Code
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))
# This code is contributed by ukasp.
Javascript
8
时间复杂度: O(N*M*M!),其中 M!是用于计算每对分数的排列数和 N*M 。
辅助空间: O(M)
高效方法:上述方法也可以使用 Bitmasking 的概念进行优化,其思想是针对向量a[][]中的每一行,尝试向量b[][]中之前未选择的所有行。使用位掩码来表示已经选择的向量b[][]行。为避免重新计算相同的子问题,请记住每个位掩码的结果。请按照以下步骤解决问题:
- 将变量行初始化为0,掩码为(2 M – 1) 。
- 用值-1初始化大小为mask + 1的向量dp[] 。
- 如果row大于等于a.size()则返回0 ,如果dp[mask]不等于-1则返回dp[mask] 。
- 将变量ans初始化为0以存储答案。
- 使用变量i遍历范围[0, a.size())并执行以下任务:
- 如果mask和2 i的按位与为真,则将变量newMask初始化为mask^(1<并将curSum 初始化为0 。
- 使用变量j迭代范围[0, a[i].size()) ,如果a[row][j]等于b[i][j]则将curSum的值增加1 。
- 将ans的值设置为ans或curSum + maxScoreSum(a, b, row+1, newmask, dp)递归的最大值。
- 完成上述步骤后,将dp[mask]的值设置为ans ,并返回ans的值作为答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the maximum defined
// score
int maxScoreSum(vector >& a,
vector >& b,
int row, int mask,
vector& dp)
{
// If all students are assigned
if (row >= a.size()) {
return 0;
}
if (dp[mask] != -1) {
return dp[mask];
}
int ans = 0;
for (int i = 0; i < a.size(); i++) {
// Check if row is not paired yet
if (mask & (1 << i)) {
int newMask = mask ^ (1 << i);
int curSum = 0;
// Check for all indexes
for (int j = 0; j < a[i].size(); j++) {
// If values at current indexes
// are same increase curSum
if (a[row][j] == b[i][j]) {
curSum++;
}
}
// Further recursive call
ans = max(
ans, curSum
+ maxScoreSum(
a, b, row + 1,
newMask, dp));
}
}
// Store the ans for current
// mask and return
return dp[mask] = ans;
}
// Utility function to find the maximum
// defined score
int maxScoreSumUtil(vector >& a,
vector >& b,
int N, int M)
{
int row = 0;
// Create a mask with all set bits
// 1 -> row is not paired yet
// 0 -> row is already paired
int mask = pow(2, M) - 1;
// Initialise dp array with -1
vector dp(mask + 1, -1);
return maxScoreSum(a, b, row, mask, dp);
}
// Driver Code
int main()
{
int N = 3, M = 3;
vector > a
= { { 1, 1, 0 }, { 1, 0, 1 }, { 0, 0, 1 } };
vector > b
= { { 1, 0, 0 }, { 0, 0, 1 }, { 1, 1, 0 } };
cout << maxScoreSumUtil(a, b, N, M);
return 0;
}
Python3
# Python 3 program for the above approach
# Function to find the maximum defined
# score
def maxScoreSum(a, b, row, mask, dp):
# If all students are assigned
if (row >= len(a)):
return 0
if (dp[mask] != -1):
return dp[mask]
ans = 0
for i in range(len(a)):
# Check if row is not paired yet
if (mask & (1 << i)):
newMask = mask ^ (1 << i)
curSum = 0
# Check for all indexes
for j in range(len(a[i])):
# If values at current indexes
# are same increase curSum
if (a[row][j] == b[i][j]):
curSum += 1
# Further recursive call
ans = max(
ans, curSum
+ maxScoreSum(
a, b, row + 1,
newMask, dp))
# Store the ans for current
# mask and return
dp[mask] = ans
return dp[mask]
# Utility function to find the maximum
# defined score
def maxScoreSumUtil(a,
b,
N, M):
row = 0
# Create a mask with all set bits
# 1 -> row is not paired yet
# 0 -> row is already paired
mask = pow(2, M) - 1
# Initialise dp array with -1
dp = [-1]*(mask + 1)
return maxScoreSum(a, b, row, mask, dp)
# Driver Code
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))
# This code is contributed by ukasp.
Javascript
8
时间复杂度: O(2 M *M*N)
辅助空间: O(2 M )