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 ...
随机推荐
- win7 cmd命令行窗口 宽度无法变大 自由调整大小
偶然遇到了这个问题,百度查到了解决方案,执行一个bat批处理命令. mode con lines=40 mode con cols=160 color 250 cls @cmd
- [wordpress]后台自定义菜单字段和使用wordpress color picker
Wordpress Version 4.4.2 参考链接 插件使用wordpress color picker:Add A New Color Picker To WordPress 后台菜单自定义字 ...
- CSS 基本知识
1.CSS 简介 CSS 指层叠样式表 (Cascading Style Sheets),是一种用来表现 HTML 文档样式的语言,样式定义如何显示 HTML 元素,是能够真正做到网页表现与结构分离的 ...
- c#通过Dotpeek调试dll
我想编程的兄弟们都要引用别人代码,哪怕是.framework里面的基础类库,也经常引用别人的一些dll,但是别人内部抛出一些异常的时候,又不知道到底怎么回事,如果这时候可以在别人的代码里面调试该多好呀 ...
- QL Server 中四种匹配符的含义
SQL中我们会见到很多的匹配符,下面解释一下 % 代表零个或者多个任意字符 _ 代表一个任意字符 [] 指定范围内的任意单个字符 [^] 不在指定范围内的任意单个字符 带有匹配符的字符串必须使用引号引 ...
- Java——String.split()函数
在java doc里有 String[] java.lang.String.split(String regex) Splits this string around matches of the g ...
- AppWidgetProvider生命周期
1.在桌面上添加小部件,让小部件可用会调用:onEnabled 2.作为通知会调用onReceive 3.小部件可用后会调用onUpdate,表明小部件状态由不可用变为可用发生了变化 4.作为通知又会 ...
- Xcode中添加代码块的方式
在写代码的过程中,经常会有重复的代码(比如说,cell的使用),当然了复制粘贴也不是不行,但是Xcode提供了一个很方便的东西. 1.在Xcode右下角你会看到有一个{}的东西,这里是一些常用的代码块 ...
- 两种js监听滚轮事件的方式
前段时间在写前端的时候,需要监听浏览器的滚轮事件 网上查了一下,找到两种监听滚轮事件的方法: 一.原生js通过window.onscroll监听 //window.onscroll = functio ...
- 以boost::function和boost:bind取代虚函数
转自:http://blog.csdn.net/Solstice/archive/2008/10/13/3066268.aspx 这是一篇比较情绪化的blog,中心思想是“继承就像一条贼船,上去就下不 ...