重(zhong)新学习悬线法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了重(zhong)新学习悬线法相关的知识,希望对你有一定的参考价值。

2017.9.28今天模拟赛T1就是求最大子矩阵的经典题

然而我已经好久没有写悬线了,以前悬线也是拉的,于是现在就系统的学习一波吧

给定一个N * M的01矩阵,求最大全0矩阵的大小

N^3的做法其实有很多种,前缀和乱搞什么的都可以

考虑N^2的做法

对于任意一个非1的点i,j,记其向上能到达的最长长度为up[i][j]

显然up[i][j] = up[i-1][j] + 1 (a[i][j] == 0)

up[i][j] = 0 (a[i][j] = 1)我们称up[i][j]为一条悬线

显然必然存在一段区间L,R满足 L<=j<=R使得1-i行中 L,R之间所有悬线都>= up[i][j]

令L[i][j]表示ij所能到达的最左端的L,R[i][j]表示i,j所能到达最右端的R

若a[i-1][j] == 0 那么L 和 R就能从i-1,j转移

能到达的最左端必然存在一个障碍或者边界挡住,右端同理

如果L,R要从上一层转移,那么新的L,R就是原先值和这一层左右离i,j最近的障碍的较劣值

显然这个可以再扫描处理为1的点时就求出来

那么对于一个点,以这个点及其悬线为中心的矩阵面积就是(R[i][j] - L[i][j] + 1) * UP[i][j]

悬线法实际上用了极大子矩阵的思想,个人能力有限,也就只能先学到这里了

下面放代码

for(int i = 1; i <= m; i++) l[i] = 1, r[i] = m;
for(int i = 1; i <= n; i++){
  int pre = 0, nxt = m + 1;
  for(int j = 1; j <= m; j++)
  if(a[i][j] == ‘1‘) pre = j, l[j] = 1; else l[j] = Max(l[j], pre + 1);
  for(int j = m; j >= 1; j--)
  if(a[i][j] == ‘1‘) nxt = j, r[j] = m; else r[j] = Min(r[j], nxt - 1);
  for(int j = 1; j <= m; j++) ans = Max(ans, (r[j] - l[j] + 1) * up[i][j]);	
}

  

 

以上是关于重(zhong)新学习悬线法的主要内容,如果未能解决你的问题,请参考以下文章

悬线法刷题记录

bzoj3039玉蟾宫 悬线法

悬线法

动态规划之悬线法

悬线法

悬线法dp