📌  相关文章
📜  通过翻转列和重新排序行来最大程度地减少将给定矩阵转换为另一个矩阵的成本

📅  最后修改于: 2021-04-26 09:58:53             🧑  作者: Mango

给定两个尺寸为N * M的二进制矩阵mat [] []target [] [] ,任务是找到使用以下操作将矩阵mat [] []转换为target [] []的最小成本:

  • 翻转mat [] []中的特定列,使所有1变为0 ,反之亦然。此操作的成本为1
  • 重新排列mat [] []的行。此操作的成本为0。

如果无法将矩阵mat [] []转换为target [] [] ,则打印“ -1”

例子:

方法:想法是将给定矩阵的行转换为位集,然后找到使矩阵相等的最小操作成本。步骤如下:

  1. 首先,使用位集将mat [] []的行转换为二进制数。
  2. 完成上述步骤后,找到所有可能的行,这些行可以是目标矩阵的第一行。
  3. 将mat [] []的行转换为tar [] []所需的翻转次数是位组的按位XOR值中设置的位的计数。
  4. 用翻转模式计算每行的按位XOR,并检查新矩阵在排序时是否等于排序后的target [] []矩阵。
  5. 如果它们相同,则存储翻转次数。
  6. 在上述步骤中计算所有此类翻转次数,并返回其中的最小值。

下面是上述方法的实现:

C++
// C++ program for the above approach
  
#include 
using namespace std;
  
// Custom comparator to sort vector
// of bitsets
bool static cmp(bitset<105>& p1,
                bitset<105>& p2)
{
    return p1.to_string() < p2.to_string();
}
  
// Function to convert the given
// matrix into the target matrix
int minCost(vector >& a,
            vector >& t)
{
  
    // Number of rows and columns
    int n = a.size();
    int m = a[0].size();
  
    vector > mat(n), tar(n);
  
    // Iterate over rows
    for (int i = 0; i < n; i++) {
        string s;
  
        for (int j = 0; j < m; j++) {
            s += char(a[i][j] + '0');
        }
        mat[i] = bitset<105>(s);
    }
  
    // Iterate over rows
    for (int i = 0; i < n; i++) {
        string s;
  
        for (int j = 0; j < m; j++) {
            s += char(t[i][j] + '0');
        }
        tar[i] = bitset<105>(s);
    }
  
    // Sort the matrix
    sort(tar.begin(), tar.end(), cmp);
  
    int ans = INT_MAX;
  
    // Check all possible rows as the
    // first row of target
    for (int i = 0; i < n; i++) {
  
        vector > copy(mat);
  
        // Get the flip pattern
        auto flip = copy[i] ^ tar[0];
  
        for (auto& row : copy)
            row ^= flip;
  
        sort(copy.begin(), copy.end(), cmp);
  
        // Number of flip operations
        // is the count of set bits in flip
        if (copy == tar)
            ans = min(ans, (int)flip.count());
    }
  
    // If it is not possible
    if (ans == INT_MAX)
        return -1;
  
    // Return the answer
    return ans;
}
  
// Driver Code
int main()
{
    // Given matrices
    vector > matrix{ { 0, 0 },
                                 { 1, 0 },
                                 { 1, 1 } };
  
    vector > target{ { 0, 1 },
                                 { 1, 0 },
                                 { 1, 1 } };
  
    // Function Call
    cout << minCost(matrix, target);
}


输出:
1


时间复杂度: O(N * M)
辅助空间: O(N * M)