poj 2559 Largest Rectangle in a Histogram (单调栈)
http://poj.org/problem?id=2559
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 12297 | Accepted: 3974 |
Description
Usually, histograms are used to represent discrete distributions, e.g., the frequencies of characters in texts. Note that the order of the rectangles, i.e., their heights, is important. Calculate the area of the largest rectangle in a histogram that is aligned at the common base line, too. The figure on the right shows the largest aligned rectangle for the depicted histogram.Input
Output
Sample Input
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
Sample Output
8
4000 思路: 题解部分转自:http://blog.csdn.net/hopeztm/article/details/7868581
题目大意:
给出一个柱形统计图(histogram), 它的每个项目的宽度是1, 高度和具体问题有关。 现在编程求出在这个柱形图中的最大面积的长方形。
例如:
7 2 1 4 5 1 3 3
7表示柱形图有7个数据,分别是 2 1 4 5 1 3 3, 对应的柱形图如下,最后求出来的面积最大的图如右图所示。

分析:
如果采用枚举的方式,如果当前我们枚举项是 i = 0, 即 height = 2,
我们用另外两个变量 j 和k 向左和向右两个方向搜素,找到第一个 小于 height的下标,这样我们就找到了用 i 项作为高度长方形了。
我们假设 -1位置,和最右高度都是无穷小。
例如:
i = 0, j = -1, k = 1, 最后的面积是 (k - j - 1) * height = 2
i = 1, j = -1, k = 7, 最后面积是( k - j - 1) * height = 7;
...
i = 3, j = 2, k = 5 面积是 ( k - j - 1) * height = 8
枚举出所有的长方形的同时,然后得到最后的面积。
不过这样的程序的时间复杂度是 O(n^2)
我们如何能仅仅做一次,就求出这个面积呢?
观察:
当我们扫扫描到第一个高度 H1 = 2的时候,我可以标记它的起始位置1, 因为我们还不知道它将向右扩展到什么地方,所以继续扫面。
当遇到第二项 H2 = 1, 因为这项比之前的小,我们知道,用H1做高度的长方形结束了,算出它的面积。
同时这个时候,我们多了一个高度H2,用它做长方形高度的长方形起始位置应该是在哪里呢? 因为H1的高度比H2要高,所以这个起始位置自然是H1所在的位置。
为了模拟上面的过程,我们引入单调栈~
我们先定义我们我们要保存的每一项数据
struct Node
{
int height;
int startPosition;
};
用来描述某一个高度,和这个高度的起始位置。
然后我们按照高度来组织成单调栈。我们来看一下它是如何工作的。
为了不用考虑堆栈为空的情况,我们用插入栈底 一个高度(0, 0)的项。
数据:
2 1 4 5 1 3 3
这样初始化
(0 , 0)
I = 1
当扫描到(2, 1)时候,因为高度2 大于栈顶,插入
(0, 0), (2, 1)
I = 2:
当扫描到1的时候,因为1小于栈顶高度2, 我们认为栈顶的那个高度应不能再向右扩展了,所以我们将它弹出
这个时候扫描到 i = 2;
高度是 (i - 1(H1.startIndex)) * H1.height = 2;
我们得到一个面积是2的长方形。
同时我们发现高度是1的当前高度,可以扩展到 H1所在的下标,所以我们插入( 1, 1) 堆栈变成
(0, 0), (1, 1) 因为(2, 1)已经不能向右伸展了,已经被弹出了
i = 3
(0, 0), (1, 1), ( 4 3)
i = 4
(0, 0), (1, 1), (4, 3), (5, 4)
i = 5
这个时候当前高度小于栈顶高度,我们认为栈顶已经不能向右扩展,所以弹出,并且获得面积 ( i - H5.startindex) * H5.height = (5 - 4 ) * 5 = 5
弹出这个元素后,其实(4, 3)的高度也要比 1 大,所以把这个也弹出来,同样方式获得面积 8.
最后我们的堆栈是
(0, 0) , (1, 1)
i = 6
(0, 0), (1, 1), ( 3, 6)
i = 7
(0, 0), (1, 1), (3, 6)
i = 8
最后一步是有点特殊的,因为我们必须要把所有的元素都弹出来,因为栈里面的高度,都坚持到了最后,我们要把这些高度组成的长方形拿出来检测。
我们可以假设扫面到8的时候,高度是0,(最小值)
弹出(3,6)获得面积 (8 - 6 ) * 3 = 6
弹出(1, 1)获得面积(8 - 1) * 1 = 7
最后的面积是8.
注意:注意取值范围,需要用到64位的int
代码:
#include <iostream>
#include <stdio.h>
#include<stack> using namespace std; struct Nod
{
__int64 height;
__int64 startPos;
}node; stack<Nod> stk; int main()
{
__int64 n,a;
while(~scanf("%I64d",&n)&&n)
{
__int64 i,maks=;
while(!stk.empty()) stk.pop();
node.height=;
node.startPos=;
stk.push(node);
for(i=;i<n;i++)
{
scanf("%I64d",&a);
node.startPos = i; //先记录当前位置,如果栈中的节点height值比a大,则弹出并更新node.startPos
while(a<stk.top().height) //注意这里不能用 a<node.height
{
node = stk.top(); //记录stk.top()顺便更新node.startPos的值,直到记录最后弹出的节点的startPos值
stk.pop();
__int64 temp = node.height * (i - node.startPos);
if(maks<temp) maks = temp; }
node.height = a;
stk.push(node); //压入栈,这里node.startPos的值视情况会有所改变的
}
//对于栈中还剩余的其他元素进行弹出处理
while(!stk.empty())
{
__int64 temp = stk.top().height * (n - stk.top().startPos);
if(maks<temp) maks = temp;
stk.pop();
}
printf("%I64d\n",maks);
}
return ;
}
题解部分转自:http://blog.csdn.net/hopeztm/article/details/7868581
poj 2559 Largest Rectangle in a Histogram (单调栈)的更多相关文章
- poj 2559 Largest Rectangle in a Histogram - 单调栈
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 19782 ...
- POJ 2559 Largest Rectangle in a Histogram(单调栈)
传送门 Description A histogram is a polygon composed of a sequence of rectangles aligned at a common ba ...
- POJ 2559 Largest Rectangle in a Histogram (单调栈或者dp)
Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15831 ...
- PKU 2559 Largest Rectangle in a Histogram(单调栈)
题目大意:原题链接 一排紧密相连的矩形,求能构成的最大矩形面积. 为了防止栈为空,所以提前加入元素(-1,0) #include<cstdio> #include<stack> ...
- [POJ 2559]Largest Rectangle in a Histogram 题解(单调栈)
[POJ 2559]Largest Rectangle in a Histogram Description A histogram is a polygon composed of a sequen ...
- stack(数组模拟) POJ 2559 Largest Rectangle in a Histogram
题目传送门 /* 题意:宽度为1,高度不等,求最大矩形面积 stack(数组模拟):对于每个a[i]有L[i],R[i]坐标位置 表示a[L[i]] < a[i] < a[R[i]] 的极 ...
- poj 2559 Largest Rectangle in a Histogram 栈
// poj 2559 Largest Rectangle in a Histogram 栈 // // n个矩形排在一块,不同的高度,让你求最大的矩形的面积(矩形紧挨在一起) // // 这道题用的 ...
- POJ2559 Largest Rectangle in a Histogram —— 单调栈
题目链接:http://poj.org/problem?id=2559 Largest Rectangle in a Histogram Time Limit: 1000MS Memory Lim ...
- 题解报告:poj 2559 Largest Rectangle in a Histogram(单调栈)
Description A histogram is a polygon composed of a sequence of rectangles aligned at a common base l ...
随机推荐
- Android_TextVIew_flow_ex1
xml文件: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns ...
- MySql安装步骤详解,MySql的root密码设置,启动MySql服务。
1.下载mysql安装包,并解压,双击mysql-5.6.24-winx64.msi 2.点击下一步 3.选择custom 4.选择安装内容和位置,5个安装内容要选择will be installed ...
- Linux系统搭建负载均衡环境
1:负载均衡的定义多台服务器组成一个集群,向外提供相同的服务,所有的请求经过apache服务器的分配,到各台tomcat服务器处理请求.另外还需实现session共享,如果有一台tomcat服务器宕机 ...
- videojs 动态加载视频
VideoJS dynamic source change via RESTful API 'Undefined' issue with changing RTMP source on compres ...
- Jquery 获取checkbox的checked问题
这个郁闷了,今天写这个功能的时候发现了问题,上网找了好多资料对照,更加纠结... 事实证明一切,自己测试了N遍,发现网上的说法和自己以前的理解都是错的,不知道大家有没发现. 下面来看看网上大多资料的说 ...
- SpringMVC文件上传 Excle文件 Poi解析 验证 去重 并批量导入 MYSQL数据库
SpringMVC文件上传 Excle文件 Poi解析并批量导入 MYSQL数据库 /** * 业务需求说明: * 1 批量导入成员 并且 自主创建账号 * 2 校验数据格式 且 重复导入提示 已被 ...
- SqlServer2005安装错误解决方法
前段时间在安装数据库SQL Server2005时,在系统检测这一步计算机报了一个错误,提示“性能监视器计数要求(错误)”,使得安装无法继续进行,于是在网上找了些方法来解决,其中有一个方法最有效,在这 ...
- Java基础从数组到集合之间关键字的区别!!!!
1.&& 和 &区别和联系: 相同点 : 结果是一样的. 不同点 :如果使用双&号判断,如果说条件一为false,不会判断条件二,但是单&号会继续判 ...
- WTL 中的常见问题汇总
1.CRect,CPoint,CSize的使用 WTL提供了CString,CRect,CPoint和CSize,可能后来版本的ATL也提供了,WTL作者推荐使用ATL的实现,所以:#include ...
- Wix: Show conditional message box
For example: Scenario: Show message box only during installation and MYPROPERTY has to be equal to & ...