POJ 2559 Largest Rectangle in a Histogram (单调栈或者dp)
Largest Rectangle in a Histogram
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 15831 Accepted: 5121 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 nintegers 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
0Sample Output
8
4000Hint
Huge input, scanf is recommended.Source
/*************************************************************************
> File Name: poj_2559.cpp
> Author: Howe_Young
> Mail: 1013410795@qq.com
> Created Time: 2015年04月08日 星期三 09时00分34秒
************************************************************************/ #include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <cstdio>
#define INF 99999999999999
using namespace std;
typedef long long LL;
const int N = ;
LL h[N], l[N], r[N];
LL Max(LL a, LL b)
{
return a > b ? a : b;
}
int main()
{
// freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
int n;
while (~scanf("%d", &n) && n)
{
memset(l, , sizeof(l));
memset(r, , sizeof(r));
for (int i = ; i <= n; i++)
scanf("%lld", &h[i]);
l[] = ; h[] = -;
r[n] = n + ; h[n + ] = -;
for (int i = ; i <= n; i++)//找左边元素
{
if (h[i] < h[i - ])
{
int tmp = l[i - ];
while (h[i] <= h[tmp])//动态规划方法找,如果不用这中方法,普通的tmp--找的话会超时
tmp = l[tmp];
l[i] = tmp;
}
else if (h[i] == h[i - ])
l[i] = l[i - ];
else
l[i] = i - ;
}
for (int i = n - ; i > ; i--)//找右边
{
if (h[i] < h[i + ])
{
int tmp = r[i + ];
while (h[i] <= h[tmp])
tmp = r[tmp];
r[i] = tmp;
}
else if (h[i] == h[i + ])
r[i] = r[i + ];
else
r[i] = i + ;
}
LL ans = -;
for (int i = ; i <= n; i++)
{
h[i] = (r[i] - l[i] - ) * h[i];
ans = Max(ans, h[i]);
}
printf("%lld\n", ans);
}
return ;
}
单调栈的思路是将这些柱子分别一个一个的判断,如果大于前面的那个那么前面比他大的就是0, 所以直接压栈,如果小于的话,弹栈,知道弹出小于它的为止,等于它,弹出来一个,压进去一个。
代码二(单调栈):
/*************************************************************************
> File Name: poj_2559_stack.cpp
> Author: Howe_Young
> Mail: 1013410795@qq.com
> Created Time: 2015年04月08日 星期三 09时48分09秒
************************************************************************/ #include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <cstdio>
#include <stack>
using namespace std;
typedef long long LL;
const int N = ;
LL h[N], r[N], l[N];
LL Max(LL a, LL b)
{
return a > b ? a : b;
}
int main()
{
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int n;
while (~scanf("%d", &n) && n)
{
memset(l, , sizeof(l));
memset(r, , sizeof(r));
for (int i = ; i <= n; i++)
scanf("%lld", &h[i]);
stack<int> S;//找出左边的元素比他大的或者等于它的个数,单调栈
S.push();//把额外的一个点压进去,防止栈弹空
h[] = h[n + ] = -;
for (int i = ; i <= n; i++)
{
if (h[i] < h[i - ])//如果后者比前者小
{
int cnt = ;
while (h[S.top()] >= h[i])
{
l[i] += l[S.top()] + ;
S.pop();
}
S.push(i);
}
else if (h[i] == h[i - ])
{
S.pop();
S.push(i);
l[i] = l[i - ] + ;
}
else
{
l[i] = ;
S.push(i);
}
}
stack<int> S2;//找处右边大于等于它的个数
S2.push(n + );
for (int i = n; i > ; i--)
{
if (h[i] < h[i + ])
{
int cnt = ;
while (h[S2.top()] >= h[i])
{
r[i] += r[S2.top()] + ;
S2.pop();
}
S2.push(i);
}
else if (h[i] == h[i + ])
{
S2.pop();
S2.push(i);
r[i] = r[i + ] + ;
}
else
{
S2.push(i);
r[i] = ;
}
}
LL ans = -;
for (int i = ; i <= n; i++)
{
h[i] *= (l[i] + r[i] + );
ans = Max(ans, h[i]);
}
printf("%lld\n", ans); }
return ;
}
过了一段时间又做了一遍。感觉代码比上面两个要好一点
代码三(单调栈):
/*************************************************************************
> File Name: largest.cpp
> Author: Howe_Young
> Mail: 1013410795@qq.com
> Created Time: 2015年09月10日 星期四 18时54分01秒
************************************************************************/ #include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm> using namespace std;
typedef long long ll;
const int maxn = ;
int a[maxn];
int L[maxn], R[maxn];
int stack[maxn];//单调递增栈
int main()
{
int n;
while (~scanf("%d", &n) && n)
{
for (int i = ; i <= n; i++)
scanf("%d", &a[i]);
a[] = a[n + ] = -;//添加两个端点位置
int top = ;
stack[++top] = ;
for (int i = ; i <= n; i++)//求出左边做远能扩展到的位置
{
if (a[i] > a[i - ])
{
L[i] = i;
stack[++top] = i;
}
else
{
while (a[stack[top]] >= a[i]) top--;
L[i] = L[stack[top + ]];
stack[++top] = i;
}
}
top = ;
stack[++top] = n + ;
for (int i = n; i >= ; i--)//右边
{
if (a[i] > a[i + ])
{
R[i] = i;
stack[++top] = i;
}
else
{
while (a[stack[top]] >= a[i]) top--;
R[i] = R[stack[top + ]];
stack[++top] = i;
}
}
long long ans = ;
for (int i = ; i <= n; i++)
ans = max(ans, (long long)a[i] * (R[i] - L[i] + ));
printf("%lld\n", ans);
}
return ;
}
POJ 2559 Largest Rectangle in a Histogram (单调栈或者dp)的更多相关文章
- 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 ...
- 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个矩形排在一块,不同的高度,让你求最大的矩形的面积(矩形紧挨在一起) // // 这道题用的 ...
- poj 2559 Largest Rectangle in a Histogram (单调栈)
http://poj.org/problem?id=2559 Largest Rectangle in a Histogram Time Limit: 1000MS Memory Limit: 6 ...
- 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 ...
随机推荐
- 知识库总结mysql常用cmd命令
打开命令目录 打开D盘mysql目录 d: cd D:\Ampps\mysql\bin 常用操作 将mysql目录下bin目录中的mysql.exe放到C:\WINDOWS下,可以执行以下命令 连接: ...
- html5系列.基础知识
兼容性问题 创建一个html5页面 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" ...
- Content-Type实体首部字段
现代互联网下,每天都会有数以亿计的各种媒体对象经由HTTP传输,如图像,文本,影视以及软件程序等.这些数据都包含在HTTP报文的实体内容中,如果把HTTP报文想像成一份快递,HTTP实体就是快递实 ...
- jQuery在on绑定事件时,使用Function.prototype.bind上下文,只能用off(event)解绑函数,否则可能导致事件叠加
因为一个bind函数,未解绑成功导致事件叠加,搞了一下午. keyup事件绑定: this.$document.on('keyup', this.keyUp.bind(this)); 原解绑函数: t ...
- Obj-C的hello,world 1
不得不说,Obj-C所谓的中缀表达式真的蛮奇怪的,当无参或者只有一个参数时看起来还不错: //无参数的方法 -(void) say; [employee say]; //只有一个参数的方法 -(voi ...
- 【Winform 控件浅谈 】 之 WebBrowser
前言 鄙人才疏学浅,如果说错了,还请各位不吝赐教 1.什么是 WebBrowser 下面是已有的轮子,我想说它们是专业的 http://baike.baidu.com/view/2981935.htm ...
- 工作总结:MFC调用Windows自带新建、保存对话框代码
保存: void CExample17Dlg::OnBnClickedSaveButton() { // TODO: Add your control notification handler cod ...
- bzoj3438
很容易想到是最小割模型首先对于一个点i,从s到i连一条容量为ai的边,再从i连一条容量为bi的边到t然后就是处理附加权的问题了一开始受到之前的思维定势的影响,一直在思考怎么在作物之间连边由于每种额外收 ...
- 【转】 Android开发之EditText属性详解
原文网址:http://blog.csdn.net/qq435757399/article/details/7947862 1.EditText输入的文字为密码形式的设置 (1)通过.xml里设置: ...
- Spfa费用流模板
; ,maxm=; ,fir[maxn],nxt[maxm],to[maxm]; int cap[maxm],val[maxm],dis[maxn],path[maxn]; void add(int ...
