Language:
题目:
Largest Rectangle in a Histogram
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 33260   Accepted: 10835

Description

A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rectangles have equal widths but may have different heights. For example, the figure on the left shows the histogram that consists of rectangles with the heights 2, 1, 4, 5, 1, 3, 3, measured in units where 1 is the width of the rectangles:


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

The input contains several test cases. Each test case describes a histogram and starts with an integer n, denoting the number of rectangles it is composed of. You may assume that 1<=n<=100000. Then follow n integers h1,...,hn, where 0<=hi<=1000000000. These numbers denote the heights of the rectangles of the histogram in left-to-right order. The width of each rectangle is 1. A zero follows the input for the last test case.

Output

For
each test case output on a single line the area of the largest
rectangle in the specified histogram. Remember that this rectangle must
be aligned at the common base line.

Sample Input

7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0

Sample Output

8
4000

Hint

Huge input, scanf is recommended.

Source


思路:

我们把每个数字都看成一个宽度为1,长度为a[i]的小矩形,我们从左向右遍历每一个小矩形,然后以这个小矩形向左向右扩展,所能向左扩展的最大值(下标)用L[i]记录下来,所能扩张的最大值(下标)用R[i]记录下来,并把所能扩展最大的矩形面积a[i]*(R[i]-L[i])记录下来,每遍历一个小矩形就动态的经行更新最大值,然后最后输出最后的值即可。

便于理解的图文:

1) 刚开始栈中为空,压入下标0;然后当i=1时,2<=1不成立,下标出栈,栈变为空,计算此时面积res=2;

2)高度1,5,6是依次递增的,所以对应下标依次压入栈中;当i=4时,6>2,下标3出栈,所以计算此时的面积res=6,如图:

3)栈顶元素为2,其对应的高度为5>2(此时,还要和下标i=4的高度比较),所以,栈顶元素2出栈,计算面积为res=10;

4)因为栈顶元素为1,其对应的高度为1<2,满足条件,所以,将i入栈,直到i=6(为压入的0此时栈中的元素为{1,4,5},有一个栈顶元素对应的高度大于i=6对应的高度,所以,5出栈,计算面积为3,其中最大面积为10;

5)栈顶元素为4,其对应高度为2>0,所以,2出栈,计算面积为4,最大面积为10;

6) 此时,栈顶元素为1,对应高度为1>0,所以,1出栈,因为1出栈以后,栈变为空,所以,计算面积的方式有变化,res=height[1]*6=6,最大面积为10。


代码1:(数组)

#include<iostream>
#include<stdio.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+;
ll a[maxn];
ll L[maxn],R[maxn];
int st[maxn];//栈的大小
int main(){
int n;
while(cin>>n&&n){
int t=;
for(int i = ;i < n;i++)
scanf("%lld",&a[i]);
for(int i=;i<n;i++){
while(t>&&a[st[t-]]>=a[i]) t--;
L[i] = t==?:(st[t-]+);
st[t++] = i;
}
t = ;
for(int i=n-;i>=;i--){
while(t>&&a[st[t-]]>=a[i]) t--;
R[i] =t ==?n:(st[t-]);
st[t++] = i;
}
ll res = ;
for(int i = ;i<n;i++){
res = max(res,a[i]*(R[i]-L[i]));
}
printf("%lld\n",res); }
return ;
}

代码2:(栈)

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<stack>
using namespace std;
typedef long long ll;
const int maxn = 1e5+;
ll h[maxn];
stack<int> s;
int main(){
int n;
while(cin>>n&&n){
memset(h,,sizeof(h));//每一组数据之前都需要初始化
while(!s.empty()) s.pop();//把栈中的元素清空
for(int i=;i<=n;i++)//i从1开始
scanf("%lld",&h[i]);
ll j=,res=;//h[]数组设为long long 类型后j也必须为long long型
while(j<=n+){//这里因为当j==n+1,是把栈中剩余的元素进行处理,例如样例中四个数全相同的时候还需最后处理一次,才能求出res的值
if(s.empty()||h[s.top()]<=h[j])
s.push(j++);
else{
ll t = s.top();
s.pop();
ll wid = s.empty()?(j-):(j-s.top()-);//这里因为第一个数组下标是从1开始的,所以当栈为空的时候,矩形的宽度必须为j-1
res = max(res,wid*h[t]);
}
}
cout<<res<<endl;
}
return ;
}

j-s.top()-1的含义:是所求矩形的宽,因为wid = L+R;

L = s.top()+1;//最左边的边界

R= j;//最右边的边界

这个栈的思路很巧,就是如果这个数符合栈中元素递增的规则或栈为空,则入栈

否则,就弹栈,这里是一个一个的弹栈操作,每弹出一个元素,就动态的更新res值,j不变,然后一直重复操作,直到栈顶元素<=要放入栈中的元素,那么就入栈

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std; typedef long long ll;
ll h[]; stack<int> s; int main()
{
int n;
while (scanf("%d", &n)&&n) {
memset(h, , sizeof(h));
while(!s.empty()) s.pop();
for (int i = ; i < n; i++) //i从0开始
scanf("%lld", &h[i]); ll j = , res = ;
while (j<=n) {
if (s.empty()||h[s.top()]<=h[j])
s.push(j++);
else {
ll t = s.top(); s.pop();
ll wid = s.empty()?j:(j-s.top()-);
res = max(res, h[t]*wid);
}
}
printf("%lld\n", res);
}
}

第一周 Largest Rectangle in a Histogram的更多相关文章

  1. poj 2559 Largest Rectangle in a Histogram (单调栈)

    http://poj.org/problem?id=2559 Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 6 ...

  2. POJ 2559 Largest Rectangle in a Histogram (单调栈或者dp)

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15831 ...

  3. hdu 1506 Largest Rectangle in a Histogram(单调栈)

                                                                                                       L ...

  4. Largest Rectangle in a Histogram HDU - 1506 (单调栈)

    A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rec ...

  5. po'j2559 Largest Rectangle in a Histogram 单调栈(递增)

    Largest Rectangle in a Histogram Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29498 ...

  6. [POJ 2559]Largest Rectangle in a Histogram 题解(单调栈)

    [POJ 2559]Largest Rectangle in a Histogram Description A histogram is a polygon composed of a sequen ...

  7. Largest Rectangle in a Histogram (最大子矩阵)

    hdu 1506 A histogram is a polygon composed of a sequence of rectangles aligned at a common base line ...

  8. NYOJ-258/POJ-2559/HDU-1506 Largest Rectangle in a Histogram,最大长方形,dp或者单调队列!

                                         Largest Rectangle in a Histogram 这么经典的题硬是等今天碰到了原题现场懵逼两小时才会去补题.. ...

  9. [POJ2559&POJ3494] Largest Rectangle in a Histogram&Largest Submatrix of All 1’s 「单调栈」

    Largest Rectangle in a Histogram http://poj.org/problem?id=2559 题意:给出若干宽度相同的矩形的高度(条形统计图),求最大子矩形面积 解题 ...

随机推荐

  1. 2019牛客多校第⑨场J Symmetrical Painting(思维,离散化)

    原题:https://ac.nowcoder.com/acm/contest/889/J 题意: 二维平面上有n个矩形,每个矩形左下角是(i−1,Li)(i−1,Li), 右上角是(i,Ri)(i,R ...

  2. CentOS 7.4安装telnet服务端

    CentOS 7.4安装telnet服务端 安装xinetd服务 # yum -y install xinetd 安装telnet-server # yum -y install telnet-ser ...

  3. CSS实现进度条

    进度条经常运用于网页,即使我们意识到不是所有的东西都将瞬间被加载完成,这些进度条用于提醒使用者关于网页上具体的任务进程,譬如上传,下载,加载应用程序等. 以前如果想要创建一个进度条的动画效果,没有使用 ...

  4. SqlServer 跨库访问

    同实例跨库 只需要 库名.dbo.表 dbo可省略 如: use Test select * from rdrecords select * from oa.dbo.UserInfo 不同实例与不同i ...

  5. CTU OPEN 2017 Go Northwest! /// 简单公式

    题目大意: 给定n个点 求任选一对点连成的直线斜率为1或-1的概率 对于点(x1,y1) 和 点(x2,y2) 斜率 k=(y1-y2)/(x1-x2) 当k=1 则 (y1-y2)/(x1-x2)= ...

  6. sort的排序及使用

    sort() 方法在适当的位置对数组的元素进行排序,并返回数组.数组会按照字符的Unicode进行排序(把数组里面当成字符串处理) 1. 按升序排列: var arr=[1,11,2,22,5,4,0 ...

  7. Elastic-Job分布式任务调度

    任务调度是指系统为了自动完成特定任务,在约定的特定时刻去执行任务的过程,有了任务调度即可解放更多的人力由系统自动去执行任务. 多线程方式实现: Timer方式实现: ScheduledExecutor ...

  8. Caused by: java.util.MissingResourceException: Can't find bundle for base name javax.servlet.LocalStrings, locale zh_CN

    这个是很早以前的一个bug了,最近开始用idea发现追源码相当方便,于是结合网上的解决方案以及自己的判断追踪一下原因,当然没有深究,只是根据提示一直追而已:先说一下解决方案: <dependen ...

  9. vue 点击切换图标

    <div @click="showImg" class="showSearch"> <img class="header_img&q ...

  10. Docker 部署 nginx 前端项目

    docker pull nginx docker run -itd -p 82:80 -v /opt/soft/nginx/conf/nginx.conf:/etc/nginx/nginx.conf ...