📌  相关文章
📜  通过配对给定矩阵中的行来最大化具有相同元素的索引计数

📅  最后修改于: 2022-05-13 01:56:04.360000             🧑  作者: Mango

通过配对给定矩阵中的行来最大化具有相同元素的索引计数

给定两个大小为M*N的二维二进制数组a[][]b[][] ,任务是将数组a[][]中的每一行与数组b[][]中的任意行配对 这样总分可以最大化,并且每对的分数被计算为两行值相同的总索引。

注意:数组b[][]的每一行只能与向量的单行配对 一个[][]

例子:

朴素方法:解决给定问题的最简单方法是生成数组 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())并执行以下任务:
    • 如果mask2 i的按位与为,则将变量newMask初始化为mask^(1<并将curSum 初始化0
    • 使用变量j迭代范围[0, a[i].size()) ,如果a[row][j]等于b[i][j]则将curSum的值增加1
    • ans的值设置为anscurSum + 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 )