Maximum full 0/1 sub-matrix

We often encounter such a problem: Given a 01 matrix, find an area in which the largest sub-matrix 0/1 full.

Simple template questions such as: [Luogu] P4147 , complex point of [Luogu] P5300

Here we introduce a relatively easy method: hanging line method

In fact, more hanging wire method is an idea, a lot of issues to maximize the sub-matrices can also use this idea to solve.

We imagine a vertical line, the upper end of this line are either border or obstacle point, then let us expand this line to the left until the point across borders and barriers.

After obtaining the position of a suspended line, we can directly calculate $ S = H (R - L + 1) $. Then take $ $ max $ is the answer to all of the $ S, correctness is obvious (not card)

The question now is: for each position, how we calculate the position of its suspension wires.

Violence algorithm considers the $ O (n ^ 3) $: We enumerate each location, then for this position, $ O (n) $ expand to other directions.

$ O (n ^ 2) $ enumeration position is already lower bound, unable to re-optimization, so we consider the optimization process of calculating the boundary.

Noting violence algorithm, a position we have to be recalculated every hanging it over the boundary line, in fact, this is not necessary, we can according to its borders before a position to launch handed the boundaries of the current location.

In particular, the definition of $ up [i] [j], left [i] [j], right [i] [j] $ represent the positions of the boundary positions $ (i, j) $, the left boundary, a right boundary of the . We can be calculated:

. 1  // n-m matrix * 
2  for ( int I = . 1 ; I <= m; I ++) right [ 0 ] [I] = m;
 . 3  for ( int I = . 1 ; I <= n-; ++ I)
 . 4  {
 . 5      int Lmax = . 1 , Rmin = m;
 . 6      for ( int J = . 1 ; J <= m; ++ J)
 . 7      {
 . 8          IF (G [I] [J]) // current position of an obstacle point 
. 9          {
 10              Lmax = J + . 1;
 . 11              up [I] [J] = left [I] [J] = 0 ;
 12 is          }
 13 is          the else 
14          {
 15              up [I] [J] up = [I - . 1 ] [J] + . 1 ; // use calculating information on line 
16              left [I] [J] = max (Lmax, left [I - . 1 ] [J]); // also take into account the left edge of the row 
. 17          }
 18 is      }
 . 19      for ( int J m =; J; - J) S
 20 is      {
 21 is          IF (G [I] [J])
 22 is          {
 23 is             J = Rmin - . 1 ;
 24              right [I] [J] = m; // set to m, to avoid affecting the calculation of the next row (row 2 and assigned row 11 is the same reason) 
25          }
 26 is          the else 
27          {
 28              right [I] [J] = min (Rmin, right [I - . 1 ] [J]);
 29              ANS = max (ANS, (right [I] [J] - left [I] [J] + . 1 ) * up [I] [J]); // calculate the area, maximum value 
30          }
 31      }
 32 }

 

Guess you like

Origin www.cnblogs.com/Aegir/p/11105131.html