Tutorialspoint.dev

Maximize the binary matrix by filpping submatrix once

Given a binary matrix of R rows and C columns. We are allowed flip to any size of sub matrix. Flipping means changing 1 to 0 and 0 to 1. The task is maximize the number of 1s in the matrix. Output the maximum number of 1s.

Examples:

Input : R = 3, C =3
mat[][] = { 0, 0, 1,
            0, 0, 1,
            1, 0, 1 }

Output : 8
Flip
0 0 1
0 0 1
1 0 1

to get

1 1 1
1 1 1
0 1 1

Input : R = 2, C = 3
mat[][] = { 0, 0, 0,
            0, 0, 0 }
Output : 6



Create a matrix ones[][] of R rows and C columns, which precomputes the number of ones in the submatrix from (0, 0) to (i, j) by

// Common elements in ones[i-1][j] and 
// ones[i][j-1] are ones[i-1][j-1]
ones[i][j] = ones[i-1][j] + ones[i][j-1] - 
             ones[i-1][j-1] + (mat[i][j] == 1)

Since, we are allowed to flip sub matrix only once. We iterate over all possible submatrices of all possible sizes for each cell (i, j) to (i + k – 1, i + k – 1). We calculate the total number of ones after the digits are filliped in the chosen submatrix.

Total number of ones in the final matrix after flipping submatrix (i, j) to (i + k – 1) will be Ones in the whole matrix – Ones in the chosen submatrix + Zeroes in the chosen sub matrix. That comes out to be :-
ones[R][C] – cal(i, j, i + k, j + k – 1) + k*k – cal(i, j, i + k – 1, j + k – 1)
where cal(a, b, c, d) denotes the number of ones in square submatrix of length c – a.

Now cal(x1, y1, x2, y2) can be define by:
ones[x2][y2] – ones[x2][y1 – 1] – ones[x1 – 1][y2] + ones[x1 – 1][y1 – 1].

Below is the implementation of this approach:

C++

// C++ program to find maximum number of ones after
// one flipping in Binary Matrix
#include <bits/stdc++.h>
#define R 3
#define C 3
using namespace std;
  
// Return number of ones in square submatrix of size
// k x k starting from (x, y)
int cal(int ones[R + 1][C + 1], int x, int y, int k)
{
    return ones[x + k - 1][y + k - 1] - ones[x - 1][y + k - 1]
           - ones[x + k - 1][y - 1] + ones[x - 1][y - 1];
}
  
// Return maximum number of 1s after flipping a submatrix
int sol(int mat[R][C])
{
    int ans = 0;
  
    // Precomputing the number of 1s
    int ones[R + 1][C + 1] = {0};
    for (int i = 1; i <= R; i++)
        for (int j = 1; j <= C; j++)
            ones[i][j] = ones[i - 1][j] + ones[i][j - 1] -
                         ones[i - 1][j - 1] +
                         (mat[i - 1][j - 1] == 1);
  
    // Finding the maximum number of 1s after flipping
    for (int k = 1; k <= min(R, C); k++)
        for (int i = 1; i + k - 1 <= R; i++)
            for (int j = 1; j + k - 1 <= C; j++)
                ans = max(ans, (ones[R][C] + k * k -
                                2 * cal(ones, i, j, k)));
    return ans;
}
  
// Driver code
int main()
{
    int mat[R][C] = {{0, 0, 1},
        { 0, 0, 1},
        { 1, 0, 1 }
    };
  
    cout << sol(mat) << endl;
  
    return 0;
}

Java

// Java program to find maximum number of ones after 
// one flipping in Binary Matrix 
class GFG {
  
static final int R = 3
static final int C = 3 ;
  
  
// Return number of ones in square submatrix of size 
// k x k starting from (x, y) 
static int cal(int ones[][], int x, int y, int k) 
    return ones[x + k - 1][y + k - 1] - ones[x - 1][y + k - 1
        - ones[x + k - 1][y - 1] + ones[x - 1][y - 1]; 
  
// Return maximum number of 1s after flipping a submatrix 
static int sol(int mat[][]) 
    int ans = 0
        int val =0;
    // Precomputing the number of 1s 
    int ones[][] = new int[R + 1][C + 1]; 
    for (int i = 1; i <= R; i++) 
        for (int j = 1; j <= C; j++) {
                    if(mat[i - 1][j - 1] == 1)
                        val=1;
        ones[i][j] = ones[i - 1][j] + ones[i][j - 1] - 
                        ones[i - 1][j - 1] + 
                        (val); 
                }
    // Finding the maximum number of 1s after flipping 
    for (int k = 1; k <= Math.min(R, C); k++) 
        for (int i = 1; i + k - 1 <= R; i++) 
            for (int j = 1; j + k - 1 <= C; j++) 
                ans = Math.max(ans, (ones[R][C] + k * k - 
                                2 * cal(ones, i, j, k))); 
    return ans; 
  
// Driver code 
    static public void main(String[] args) {
        int mat[][] = {{0, 0, 1}, 
        { 0, 0, 1}, 
        { 1, 0, 1
    }; 
  
       System.out.println(sol(mat)); 
    }
}
  
// This code is contributed by Rajput-Ji

Python3

# Python 3 program to find maximum number of 
# ones after one flipping in Binary Matrix
R = 3
C = 3
  
# Return number of ones in square submatrix 
# of size k x k starting from (x, y)
def cal(ones, x, y, k):
    return (ones[x + k - 1][y + k - 1] - 
            ones[x - 1][y + k - 1] - 
            ones[x + k - 1][y - 1] + 
            ones[x - 1][y - 1])
  
# Return maximum number of 1s after 
# flipping a submatrix
def sol(mat):
    ans = 0
  
    # Precomputing the number of 1s
    ones = [[0 for i in range(C + 1)] 
               for i in range(R + 1)]
    for i in range(1, R + 1, 1):
        for j in range(1, C + 1, 1):
            ones[i][j] = (ones[i - 1][j] + ones[i][j - 1] - 
                          ones[i - 1][j - 1] + 
                         (mat[i - 1][j - 1] == 1))
  
    # Finding the maximum number of 1s
    # after flipping
    for k in range(1, min(R, C) + 1, 1):
        for i in range(1, R - k + 2, 1):
            for j in range(1, C - k + 2, 1):
                ans = max(ans, (ones[R][C] + k * k - 2 * 
                            cal(ones, i, j, k)))
    return ans
  
# Driver code
if __name__ == '__main__':
    mat = [[0, 0, 1],
           [0, 0, 1],
           [1, 0, 1]]
  
    print(sol(mat))
  
# This code is contributed by
# Sahil_Shelangia

C#

// C# program to find maximum number of ones after 
// one flipping in Binary Matrix 
using System;    
  
public class GFG { 
  
    static readonly int R = 3; 
    static readonly int C = 3 ; 
  
  
    // Return number of ones in square submatrix of size 
    // k x k starting from (x, y) 
    static int cal(int [,]ones, int x, int y, int k) 
    
        return ones[x + k - 1,y + k - 1] - ones[x - 1,y + k - 1] 
            - ones[x + k - 1,y - 1] + ones[x - 1,y - 1]; 
    
  
    // Return maximum number of 1s after flipping a submatrix 
    static int sol(int [,]mat) 
    
        int ans = 0; 
            int val =0; 
        // Precomputing the number of 1s 
        int [,]ones = new int[R + 1,C + 1]; 
        for (int i = 1; i <= R; i++) 
            for (int j = 1; j <= C; j++) { 
                        if(mat[i - 1,j - 1] == 1) 
                            val=1; 
            ones[i,j] = ones[i - 1,j] + ones[i,j - 1] - 
                            ones[i - 1,j - 1] + 
                            (val); 
                    
        // Finding the maximum number of 1s after flipping 
        for (int k = 1; k <= Math.Min(R, C); k++) 
            for (int i = 1; i + k - 1 <= R; i++) 
                for (int j = 1; j + k - 1 <= C; j++) 
                    ans = Math.Max(ans, (ones[R,C] + k * k - 
                                    2 * cal(ones, i, j, k))); 
        return ans; 
    
  
    // Driver code 
    static public void Main() { 
        int [,]mat = {{0, 0, 1}, 
        { 0, 0, 1}, 
        { 1, 0, 1 } 
    }; 
  
    Console.WriteLine(sol(mat)); 
    
// This code is contributed by 29AjayKumar

PHP

<?php
// PHP program to find maximum number of ones after
// one flipping in Binary Matrix
  
$R = 3;
$C = 3;
  
// Return number of ones in square submatrix of size
// k x k starting from (x, y)
function cal($ones, $x, $y, $k)
{
    return $ones[$x + $k - 1][$y + $k - 1] -
            $ones[$x - 1][$y + $k - 1] -
            $ones[$x + $k - 1][$y - 1] + 
            $ones[$x - 1][$y - 1];
}
  
// Return maximum number of 1s after flipping a submatrix
function sol($mat)
{
    global $C,$R;
    $ans = 0;
  
    // Precomputing the number of 1s
    $ones=array_fill(0,$R + 1,array_fill(0,$C + 1,0));
    for ($i = 1; $i <= $R; $i++)
        for ($j = 1; $j <= $C; $j++)
            $ones[$i][$j] = $ones[$i - 1][$j] + $ones[$i][$j - 1] -
                        $ones[$i - 1][$j - 1] +
                        (int)($mat[$i - 1][$j - 1] == 1);
  
    // Finding the maximum number of 1s after flipping
    for ($k = 1; $k <= min($R, $C); $k++)
        for ($i = 1; $i + $k - 1 <= $R; $i++)
            for ($j = 1; $j + $k - 1 <= $C; $j++)
                $ans = max($ans, ($ones[$R][$C] + $k * $k -
                                2 * cal($ones, $i, $j, $k)));
    return $ans;
}
  
    // Driver code
    $mat = array(array(0, 0, 1),
        array( 0, 0, 1),
        array( 1, 0, 1 ));
  
    echo sol($mat);
  
// This code is contributed by mits
?>

Output:

8

Time Complexity: O(R*C*min(R, C))

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.



This article is attributed to GeeksforGeeks.org

leave a comment

code

0 Comments

load comments

Subscribe to Our Newsletter