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 ...
随机推荐
- html框架集 js刷新页面方法大全
一.先来看一个简单的例子: 下面以三个页面分别命名为frame.html.top.html.bottom.html为例来具体说明如何做. frame.html 由上(top.html)下(bottom ...
- sql 学习之 group by 及 聚合函数
1.在使用 GROUP BY 子句时,Select列表中的所有列必须是聚合列(SUM,MIN/MAX,AVG等)或是GROUP BY 子句中包括的列.同样,如果在SELECT 列表中使用聚合列,SEL ...
- 如何从BBC网站学习英语
- WebKit JavaScript Binding添加新DOM对象的三种方式
一.基础知识 首先WebKit IDL并非完全遵循Web IDL,只是借鉴使用.WebKit官网提供了一份说明(WebKitIDL),比如Web IDL称"operation”(操作), 而 ...
- Delphi控件的透明与不透明(要挨个解释一下原因),对InvalidateControl的关键理解
procedure TForm1.Button3Click(Sender: TObject);begin if (csOpaque in ControlStyle) then ShowMessage( ...
- War3Tool dota改键v3.3版
wartool魔兽全屏改键功能:1.支持11平台自定义改建,自动进局域网(同类软件暂时没发现这个功能)2.技能改键,可以有效的切换适合你的技能键3.war3路径扫描,运行本程序一键就能打开war3 ( ...
- -_-#【CSS】注释
- AC自动机:BZOJ 2434 阿狸的打字机
2434: [Noi2011]阿狸的打字机 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1834 Solved: 1053[Submit][Sta ...
- select的使用(二)
多表查询 /*基本连接*/ select a.Name,b.Name from T_Employee a,T_Department b where a.DepartmentId=b.Id /*内连接, ...
- Entity Framwork db First 中 Model验证解决办法。
由于项目中用到 Entity Framwork db First 每次从数据库生成数据模型之后都会把模型更新. 只要有一个表更新.所有的类都会重新生成. 在网上找了各种例子都是差不多的, 可能 ...