单调栈 poj2559 Largest Rectangle in a Histogram

传送门:点击打开链接

题意:求最大长方形。

思路:以前看训练指南上有利用动态规划的方法求最大子矩阵,但是空间复杂度和实现起来都比较麻烦

利用单调栈来做这题,代码异常简洁明了。维护一个单调栈,从栈底到栈顶是单调递增的。

每一次将一个数加入到栈中时,都要先看栈顶是否有数字大于等于这个数字,如果有就弹起,把这个数字的权值累加到准备加入到栈中的那个数字上去

因为,弹出去的那些高度都比这个要高,所以如果以这个为最高的,那么左边那些是肯定会比这个高或者等于这个高度的

然后求左边范围,求右边范围,组合起来就是答案了

#include<map>
#include<set>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck(x) cout<<"["<<x<<"]"
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;

const int MX = 1e5 + 5;

int A[MX], L[MX], R[MX];
int S[MX], rear;

int main() {
    int n; //FIN;
    while(~scanf("%d", &n), n) {
        for(int i = 1; i <= n; i++) {
            scanf("%d", &A[i]);
        }

        rear = 0;
        for(int i = 1; i <= n; i++) {
            L[i] = 1;
            while(rear && A[S[rear - 1]] >= A[i]) L[i] += L[S[--rear]];
            S[rear++] = i;
        }

        rear = 0;
        for(int i = n; i >= 1; i--) {
            R[i] = 1;
            while(rear && A[S[rear - 1]] >= A[i]) R[i] += R[S[--rear]];
            S[rear++] = i;
        }

        LL ans = 0;
        for(int i = 1; i <= n; i++) {
            ans = max(ans, (LL)A[i] * (L[i] + R[i] - 1));
        }
        printf("%I64d\n", ans);
    }
    return 0;
}


你可能感兴趣的:(单调栈 poj2559 Largest Rectangle in a Histogram)