最大矩形求解问题(单调递减栈)

来源:互联网 发布:java 字典序排序 代码 编辑:程序博客网 时间:2024/04/29 00:30

POJ2559 最大矩形面积,POJ2796 区间最大值

问题:求解给定的直方图中可以组成的矩形的最大面积值,假定每个格子的长度为1,如图所示,最大面积为阴影部分组成的矩形。



解析


最常规的算法就是选定一个高度为h的格子,然后以该格子为中心向左和向右扩展,然后得到其面积值=h*(r-l); 这个可以建模为:对一个序列,以其中一个元素O为中心,左右扩展得到一个比O大的元素构成的连续区间n,面积=元素值O*|a|,例如 1,5,2,4,3序列,以2为中心可得到[5,2,4,3]组成的区间,面积等于2*4,其中4为区间中元素的个数;

在这里,如果相乘的不是个数而是区间元素的和,那么就是该问题的变体,其实质是等价的。
如果利用常规算法,以每一个为元素为中心左右搜索,则算法复杂度为O(n*n),注意到这里有些元素可能是重复的计算,可以考虑用到动态规划,可以利用类似单调递增(减)栈的东西,保存之前的值,从而使得算法复杂度变为O(n)

具体算法思路如下

为了便于宽度累加定义元素的结构为(高度,宽度),高度作为判断依据构成单调递减栈,宽度在出栈时进行累加更新。
(1)如果栈为空或者当前元素大于等于栈顶元素的话则直接进栈。
(2)若当前元素小于栈顶元素或者原始序列为空,则栈顶元素执行出栈,并伴随以下动作:
        1)更新所构成矩形的面积值,若大于最大面积值则更新最大值。
        2)将栈顶元素的宽度值累加到栈顶下一个元素的宽度值上。
(3)重复上面步骤,直到原始序列为空,栈为空,则得到最大的面积值

演示步骤:

以下为整个演示过程,注意:
(1)括号里由(高度,宽度)组成,按照上面所说的算法进行入栈、更新步骤
(1)白色---》黑色表示入栈动作
(2)黑色---》白色表示出栈动作,出栈时需要传递宽度值,以及更新当前面积值
(3)红色表示宽度值和当前面积值的更新
(4)在更新过程中,保存当前最大的面积值,在栈空时算法结束。
(5)本例子的顺序为1,2,3,1,2



1 0
原创粉丝点击