《浅谈用极大化思想解决最大子矩形问题》
作者:王知昆


首先,根据定理1:最大有效子矩形一定是一个极大子矩形。不过与前一种算法不同的是,我们不再要求每一次枚举的一定是极大子矩形而只要求所有的极大子矩形都被枚举到。看起来这种算法可能比前一种差,其实不然,因为前一种算法并不是完美的:虽然每次考察的都是极大子矩形,但它还是做了一定量的“无用功”。可以发现,当障碍点很密集的时候,前一种算法会做大量没用的比较工作。要解决这个问题,我们必须跳出前面的思路,重新考虑一个新的算法。注意到极大子矩形的个数不会超过矩形内单位方格的个数,因此我们有可能找出一种时间复杂度是O(N×M)的算法。

定义:

有效竖线:除了两个端点外,不覆盖任何障碍点的竖直线段。

悬线:上端点覆盖了一个障碍点或达到整个矩形上端的有效竖线。如图所示的三个有效竖线都是悬线。

对于任何一个极大子矩形,它的上边界上要么有一个障碍点,要么和整个矩形的上边界重合。那么如果把一个极大子矩形按x坐标不同切割成多个(实际上是无数个)与y轴垂直的线段,则其中一定存在一条悬线。而且一条悬线通过尽可能地向左右移动恰好能得到一个子矩形(未必是极大子矩形,但只可能向下扩展)。通过以上的分析,我们可以得到一个重要的定理。

定理3】:如果将一个悬线向左右两个方向尽可能移动所得到的有效子矩形称为这个悬线所对应的子矩形,那么所有悬线所对应的有效子矩形的集合一定包含了所有极大子矩形的集合。

定理3中的“尽可能”移动指的是移动到一个障碍点或者矩形边界的位置。

根据【定理3】可以发现,通过枚举所有的悬线,就可以枚举出所有的极大子矩形。由于每个悬线都与它底部的那个点一一对应,所以悬线的个数=(n-1)×m(以矩形中除了顶部的点以外的每个点为底部,都可以得到一个悬线,且没有遗漏)。如果能做到对每个悬线的操作时间都为O(1),那么整个算法的复杂度就是O(NM)。这样,我们看到了解决问题的希望。

现在的问题是,怎样在O(1)的时间内完成对每个悬线的操作。我们知道,每个极大子矩形都可以通过一个悬线左右平移得到。所以,对于每个确定了底部的悬线,我们需要知道有关于它的三个量:顶部、左右最多能移动到的位置。对于底部为(i,j)的悬线,设它的高为hight[i,j],左右最多能移动到的位置为left[i,j],right[i,j]。为了充分利用以前得到的信息,我们将这三个函数用递推的形式给出。

对于以点(i,j)为底部的悬线:

如果点(i-1,j)为障碍点,那么,显然以(i,j)为底的悬线高度为1,而且左右均可以移动到整个矩形的左右边界,即

height[i,j]=l

left[i,j]=0

right[i,j]=m

如果点(i-1,j)不是障碍点,那么,以(i,j)为底的悬线就等于以(i-1,j)为底的悬线+点(i,j)到点(i-1,j)的线段。因此,height[i,j]=height[i-1,j]+1。比较麻烦的是左右边界,先考虑left[i,j]。如下图所示,(i,j)对应的悬线左右能移动的位置要在(i-1,j)的基础上变化。

即left[i,j]=max( left[i-1,j] , (i-1,j)左边第一个障碍点位置 ) 如图

right[i,j]的求法类似。综合起来,可以得到这三个参数的递推式:

height[i,j]=height[i-1,j]+1

left[i,j]=max(left[i-1,j] , (i-1,j)左边第一个障碍点位置,边界0也是障碍点)

right[i,j]=max( right[i-1,j] , (i-1,j)右边第一个障碍点位置,边界m也是障碍点 )

这样做充分利用了以前得到的信息,使每个悬线的处理时间复杂度为O(1)。对于以点(i,j)为底的悬线对应的子矩形,它的面积为(right[i,j]-left[i,j])*height[i,j]。

这样最后问题的解就是:

Result=max(right[i,j]-left[i,j])*height[i,j] (l<=i<n, l<=j<=m)

整个算法的时间复杂度为O(NM),空间复杂度是O(NM)。

[Repost] 悬线法的更多相关文章

  1. 【BZOJ-1127】KUP 悬线法 + 贪心

    1127: [POI2008]KUP Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 317  Solved: 11 ...

  2. 【BZOJ-3039&1057】玉蟾宫&棋盘制作 悬线法

    3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 753  Solved: 444[Submit][Status][Discuss] D ...

  3. BZOJ_3039_玉蟾宫_(动态规划+悬线法)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3039 n*m的矩阵由R和F组成,求全是F的子矩阵的大小的三倍. 分析 悬线法: 浅谈用极大化思 ...

  4. BZOJ 1057: [ZJOI2007]棋盘制作( dp + 悬线法 )

    对于第一问, 简单的dp. f(i, j)表示以(i, j)为左上角的最大正方形, f(i, j) = min( f(i + 1, j), f(i, j + 1), f(i + 1, j + 1)) ...

  5. BZOJ 3039: 玉蟾宫( 悬线法 )

    最大子矩阵...悬线法..时间复杂度O(nm) 悬线法就是记录一个H向上延伸的最大长度(悬线), L, R向左向右延伸的最大长度, 然后通过递推来得到. ----------------------- ...

  6. [POJ1964]City Game (悬线法)

    题意 其实就是BZOJ3039 不过没权限号(粗鄙之语) 同时也是洛谷4147 就是求最大子矩阵然后*3 思路 悬线法 有个博客讲的不错https://blog.csdn.net/u012288458 ...

  7. [P1169] 棋盘制作 &悬线法学习笔记

    学习笔记 悬线法 最大子矩阵问题: 在一个给定的矩形中有一些障碍点,找出内部不包含障碍点的,边与整个矩形平行或重合的最大子矩形. 极大子矩型:无法再向外拓展的有效子矩形 最大子矩型:最大的一个有效子矩 ...

  8. P1169 [ZJOI2007]棋盘制作 DP悬线法

    题目描述 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8 \times 88×8大小的黑白相间的方阵,对应八八六十四卦,黑白 ...

  9. P4147 玉蟾宫 二维DP 悬线法

    题目背景 有一天,小猫rainbow和freda来到了湘西张家界的天门山玉蟾宫,玉蟾宫宫主蓝兔盛情地款待了它们,并赐予它们一片土地. 题目描述 这片土地被分成N*M个格子,每个格子里写着'R'或者'F ...

随机推荐

  1. AtCoder Grand Contest 012 A - AtCoder Group Contest(贪心)

    Time limit : 2sec / Memory limit : 256MB Score : 300 points Problem Statement There are 3N participa ...

  2. Ionic4 入门

    1.搭建环境 1.电脑安装node.js,安装后电脑会自动安装npm     2.通过cmd命令,安装cnpm npm install -g cnpm -registry=https://regist ...

  3. Maven Could not open ServletContext resource [/WEB-INF/applicationContext.xml]

    因此:maven中,配置文件的读取应有下列红字两部分,缺一不可. 不是maven项目时,可以都不写........ <context-param> <param-name>co ...

  4. Html5 学习笔记 --》css3 学习

    在开发任务中最好不要使用前缀 可以设置发散图形 圆形 方形等 边框图片效果: CSS3 变形效果: Css3 3D立体变形: css 设置 CSS3 过度效果: div:hover { backgro ...

  5. Appium移动端自动化:Api接口详解

    滑动操作与拖拽操作 # 滚动处理 # elementObj1 目标滚动元素,elementObj2 起始滚动元素 # 底层通过action操作,与web ui相反,origin_el为目标元素,des ...

  6. HTML设置span宽度

    CSS中的 width 属性并不总是有效的如果对象是 inline 对象,width 属性就会被忽略,Firefox 和 IE 是遵循CSS标准,因而直接设置span宽度会无效. 解决:span { ...

  7. C语言深度剖析自测题8解析

    #include <stdio.h> int  main(void) {    int  a[5] = {1, 2, 3, 4, 5}; int* ptr1 = (int*)(&a ...

  8. leetcode.双指针.524通过删除字母匹配到字典里最长单词-Java

    1. 具体题目 给定一个字符串和一个字符串字典,找到字典里面最长的字符串,该字符串可以通过删除给定字符串的某些字符来得到.如果答案不止一个,返回长度最长且字典顺序最小的字符串.如果答案不存在,则返回空 ...

  9. 《代码大全2》读书笔记 Week 1

    <代码大全2>第一.二.三章 隐喻思维在西方是一个热门的话题,隐喻的认知功能在各个学科正受到越来越多的重视,依照我的理解,其实就是以众所周知或者理解主体熟悉的事物为符号去将新事物.新概念具 ...

  10. 2019-9-2-win10-uwp-隐私声明

    title author date CreateTime categories win10 uwp 隐私声明 lindexi 2019-09-02 12:57:38 +0800 2018-2-13 1 ...