POJ 2559单调栈

题目大意:

给出一个柱形统计图(histogram), 它的每个项目的宽度是1, 高度和具体问题有关。 现在编程求出在这个柱形图中的最大面积的长方形。

例如: 

7 2 1 4 5 1 3 3

7表示柱形图有7个数据,分别是 2 1 4 5 1 3 3, 对应的柱形图如下,最后求出来的面积最大的图如右图所示。

思路:求矩形面积就是要知道宽和高,我们以每一个小矩形为高向两边扩展(扩展到l 和 r),则面积就为h*(r - l);

对于前面矩形比我当前扫到点要高,那么这个矩形的 l 必定是前一个矩形的 l .所以我们可以用单调栈维护;

正着扫一遍可以得到所有的 l ; 倒着扫一遍得到所有的 r ;

详见代码:

View Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;

#define LL long long
#define max(a,b) ((a)<(b)?(b):(a))

const int Max = 100009;
struct node {
    LL h;
    int l,r;
}col[Max];

node que[Max];

int main() {
    int n;
    while(scanf("%d",&n) == 1) {
        if(n==0)
            break;
        for(int i = 0; i < n; i++)
            scanf("%lld",&col[i].h);
        int top = 0;
        col[0].l = 0;
        que[top] = col[0];
        for(int i = 1; i < n; i++) {
            if(col[i].h > que[top].h) {
                col[i].l = i;
            }
            else{
                while(col[i].h <= que[top].h && top >= 0){
                    col[i].l = que[top].l;
                    top--;
                }
            }
            que[++top] = col[i];
        }
        top = 0;
        col[n-1].r = n;
        que[top] = col[n-1];
        for(int i = n-2; i >= 0; i--) {
            if(col[i].h > que[top].h) {
                col[i].r = i + 1; 
            }
            else {
                while(col[i].h <= que[top].h && top >= 0) {
                    col[i].r = que[top].r;
                    top--;
                }
            }
            que[++top] = col[i];
        }
        LL ans = 0;
        for(int i = 0; i < n; i++) {
            if(col[i].h * (col[i].r - col[i].l) > ans)
                ans = col[i].h * (col[i].r - col[i].l);
        }
        cout << ans << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/gray035/p/3001665.html