| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 17105 | Accepted: 5531 |
Description

Input
Output
Sample Input
7 2 1 4 5 1 3 3 4 1000 1000 1000 1000 0
Sample Output
8 4000
Hint
题意:柱状图是由一些宽度相等的长方形下端对齐后横向排列得到的图形。现在有由n个宽度为1,高度分别为h1,h2,……,hn的长方形从左到右依次排列组成的柱状图。问里面包含的长方形的最大面积是多少。
分析:如果我们能够预处理出以每个高度为高的长方形的左端点le[i]以及右端点ri[i],那么就可以用O(n)的复杂度扫一遍就可以得到最大值。如何预处理出le[i]以及ri[i]呢?这里就要运用栈的知识点了。先考虑le[i]的情况,定义一个栈head,并且初始化为空。然后不断增加i的值,并且维护这个栈使得它按照下面得顺序存储用于推算后面的le值得元素:
设栈中元素从上到下的值为X(i),则X(i) > X(i+1)且h(X(i)) > h(X(i+1))。
计算ri[i]的时候按照同样的方法求即可。
题目链接:http://poj.org/problem?id=2559
代码清单:
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<cstdio>
#include<string>
#include<cctype>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
const int maxn = 100000 + 5;
int n;
ll h[maxn];
ll le[maxn],ri[maxn];
stack<int>head;
stack<int>tail;
void init(){
while(!head.empty()) head.pop();
while(!tail.empty()) tail.pop();
memset(le,0,sizeof(le));
memset(ri,0,sizeof(ri));
}
void input(){
for(int i=1;i<=n;i++)
scanf("%I64d",&h[i]);
}
ll work(){
for(int i=1;i<=n;i++){
while(!head.empty()&&h[head.top()]>=h[i]) head.pop();
if(head.empty()) le[i]=1;
else le[i]=head.top()+1;
head.push(i);
}
for(int i=n;i>=1;i--){
while(!tail.empty()&&h[tail.top()]>=h[i]) tail.pop();
if(tail.empty()) ri[i]=n;
else ri[i]=tail.top()-1;
tail.push(i);
}
ll res=-1;
for(int i=1;i<=n;i++){
res=max(res,h[i]*(ri[i]-le[i]+1));
}
return res;
}
void solve(){
printf("%I64d\n",work());
}
int main(){
while(scanf("%d",&n)!=EOF&&n){
init();
input();
solve();
}return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
POJ_2559_Largest Rectangle in a Histogram(栈)
原文:http://blog.csdn.net/jhgkjhg_ugtdk77/article/details/47839297