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
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 ...
随机推荐
- MAC 环境下初始化mysql root 密码
1. 关掉mysql服务,打开系统设置最后的mysql,然后将mysql先关掉 2. 生成一个文件命名mysql-init,文件中放入:一句话,这句话不同版本不一样,如下:(括号里面不包含) alte ...
- 【排障】nginx在reload时候报错invalid PID number
nginx在reload时候报错invalid PID number nginx重新加载配置文件时候报错,提示无效的PID: 解决的办法有二: 第一种思路是因为是加载配置文件报的错,所以用-c 选项指 ...
- Linux系统(将web应用部署到tomcat服务器上)
一:tomcat服务开机自启动 将启动命令路径配置到/etc/profile文件中在/etc/profile 文件最后配置 /usr/tomcat/apache-tomcat-6.0.45/bin/s ...
- MATLAB的循环结构
循环结构有两种基本形式:while 循环和for 循环.两者之间的最大不同在于代码的重复是如何控制的.在while 循环中,代码的重复的次数是不能确定的,只要满足用户定义的条件,重复就进行下去.相对地 ...
- 浅谈在实验室的一个作品---8x8x8光立方
在实验室学习51单片机之后,觉得是得做点东西,提高一下动手能力,光立方就成了自己忙碌的目标.买了1000个灯,准备好之后就开始了为期一周的焊接, 一周之后就是这个样子啦.... 之后就进行了电路板的焊 ...
- 本地环境phpStorm10+XDebug配置和断点调试
安装环境:XAMPP;phpStorm版本10; windows 7 64bit. XAMPP.phpStorm 都直接安装在了D盘根目录,9999m目录建在D:\xampp\htocts下,即目录工 ...
- [记录]calculate age based on date of birth
calculate age based on date of birth know one new webiste:eval.in run php code
- 在centos中php 在连接mysql的时候,出现Can't connect to MySQL server on 'XXX' (13)
原文连接:http://hi.baidu.com/zwfec/item/64ef5ed9bf1cb3feca0c397c 红色的是命令 SQLSTATE[HY000] [2003] Can't con ...
- [转]分布式系统为什么需要 Tracing?
分布式系统为什么需要 Tracing? 先介绍一个概念:分布式跟踪,或分布式追踪. 电商平台由数以百计的分布式服务构成,每一个请求路由过来后,会经过多个业务系统并留下足迹,并产生对各种Cach ...
- Android调用系统相机以及自定义相机
0.综述 自定义相机,此处展示简单的相机功能,官方文档中还有相应关于视频拍摄的内容,此处不提 1.添加权限 <!--相机权限,数据存储--> <uses-permission and ...