POJ 2559 Largest Rectangle in a Histogram

1.题目描述:点击打开链接

2.解题思路:本题利用单调栈解决。单调栈是满足从栈顶到栈底,元素大小严格递增或者严格递减的栈。对于本题,如果我们可以知道以i为端点,向左可以最远延伸的距离和向右最远延伸的距离,那么最大面积res=max{hi*(R[i]-L[i])|0<=i<n}。

那么如何高效地计算L[i]和R[i]呢?通过观察我们发现如果在某一处p有h[p]<h[i]。那么L[i]就是p+1,否则,可以继续往左扩展。同样的方法可以处理R[i]。由此我们可以利用单调栈的特性来处理,因为它内部的元素是单调递增的,因此只需要一直的弹栈,直到满足h[top]<h[i]结束即可,然后将i入栈。

3.代码:

//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<functional>
using namespace std;

#define me(s)  memset(s,0,sizeof(s))
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair <int, int> P;

const int N=100000+10;
int h[N];
int L[N],R[N];
int st[N];

int main()
{
    int n;
    while(~scanf("%d",&n)&&n)
    {
        for(int i=0;i<n;i++)
            scanf("%d",&h[i]);
        int t=0;
        for(int i=0;i<n;i++)  //计算L[i]
        {
            while(t>0&&h[st[t-1]]>=h[i])t--;
            L[i]=!t?0:st[t-1]+1;
            st[t++]=i;
        }
        t=0;
        for(int i=n-1;i>=0;i--)//计算R[i]
        {
            while(t>0&&h[st[t-1]]>=h[i])t--;
            R[i]=!t?n:st[t-1];  //注意不要写成st[t-1]-1,因为我们要的是[L,R),最后序列长度就是R-L
            st[t++]=i;
        }
        ll res=0;
        for(int i=0;i<n;i++)
            res=max(res,(ll)h[i]*(R[i]-L[i]));
        printf("%lld\n",res);
    }
}


你可能感兴趣的:(单调栈,扫描与维护)