最大矩形求解问题(单调递减栈)
2016-03-22 13:35
162 查看
POJ2559 最大矩形面积,POJ2796
区间最大值
问题:求解给定的直方图中可以组成的矩形的最大面积值,假定每个格子的长度为1,如图所示,最大面积为阴影部分组成的矩形。
![](file:///C:/Users/npu/AppData/Local/YNote/data/lanshanxunmeng@163.com/7d4dcb57683e408e8882869f92e977c0/clipboard.png)
解析:
最常规的算法就是选定一个高度为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
![](file:///C:/Users/npu/AppData/Local/YNote/data/lanshanxunmeng@163.com/7a94ebb1ea1a4e22b9ecb1faad6bf5a0/clipboard.png)
![](file:///C:/Users/npu/AppData/Local/YNote/data/lanshanxunmeng@163.com/99937f085771493687444ccb4807e56b/clipboard.png)
![](file:///C:/Users/npu/AppData/Local/YNote/data/lanshanxunmeng@163.com/2d66abded0594b80ad020d0934ab6801/clipboard.png)
相关文章推荐
- python中小用法之assert,*arg,**arg用法全解
- facebook bigpipe
- 求各位数字之和
- 理解JavaScript中的作用域和上下文
- Java Generics and Collections-2.2
- HTTP使用BASIC认证的原理及实现方法
- 如何使用工具进行线上 PHP 性能追踪及分析?
- WPF MVVM之INotifyPropertyChanged接口的几种实现方式
- UDP通信总结
- 百度地图3.7.1的配置
- JAVA集合的学习
- oracle、sqlserver、mysql常用函数对比[to_char、to_number、to_date]
- Xentrace使用教程
- TinyXml Print 函数 Bug
- iOS 图片左右反转 反向
- 移动web页面前端开发总结
- Qt5自带加密方法
- ftrace的使用【转】
- 检测数据库各实例session 阻塞 tree的sql
- 常用正则表达式整理