POJ-2559Largest Rectangle in a Histogram(单调栈)

题目链接:http://poj.org/problem?id=2559

题目大意:给你n个长方形,每个长方形的高为$h_i$,底为1,问最大的矩形面积可以是多少

Sample Input

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

Sample Output

8
4000

emmmm,暴力计算的话就是看看两边能够最多延伸到哪里,那么我们可以用单调栈来维护一个递增的矩形,那么它就不需要再检查左边的,在添加新元素的时候,如果比栈顶元素大,直接往里面扔,否则的话我们就需要一点操作了。

想想我们单调栈维护的是每个元素向左边能够延伸的最小的坐标,也就是最大长度,那么当剔除掉栈顶的时候,我们就需要对栈顶直接进行计算:$ans=max(ans,1LL*(i-stk[tail])*h[stk[tail]])$,我相信这个很好理解,$i$是向右延伸的最大坐标+1,$stk[tail]$是向左延伸的最小坐标。最后,剔除完成之后,我们知道,第$i$个位置也可以延伸到这里,那么也就是说$stk[++tail]=stk[tail]$,同时我们将这个位置的高度也进行变化:$h[stk[tail]]=h[i]$。。。那么代码也就基本出来了。

以下是A

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long ll;
const int mac=1e5+10;

ll h[mac];
int stk[mac];

int main()
{
    int n;
    while (scanf ("%d",&n)){
        if (!n) return 0;
        for (int i=1; i<=n; i++)
            scanf ("%lld",&h[i]);
        int head=1,tail=0;
        ll ans=0;
        h[n+1]=-1;
        for (int i=1; i<=n+1; i++){
            if (head>tail || h[stk[tail]]<=h[i]) {stk[++tail]=i; continue;}
            while (head<=tail && h[stk[tail]]>h[i]){
                ans=max(ans,1LL*(i-stk[tail])*h[stk[tail]]);
                tail--;    
            }
            stk[++tail]=stk[tail]; 
            h[stk[tail]]=h[i];
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

C代码:

 

posted @ 2020-07-08 15:29  lonely_wind  阅读(135)  评论(0编辑  收藏  举报