【单调栈 && 左右两边第一个比它小的数】POJ - 2559 Largest Rectangle in a Histogram

Step1 Problem:

给你n个连续宽为1的长方形,高为a[i]。
里面包含的长方形最大的面积是多少?
数据范围:
1<=n<=1e5, 0 <= a[i] <= 1e9.
例子:
Input:
7 2 1 4 5 1 3 3
4 1000 1000 1000 1000
0
Output:
8
4000

Step2 Ideas

对于每个i, 我们只需要 求出 左边高度第一个比它小的下标L[i] 和 右边高度第一个比它小的下标R[i]。
第i个长方形为高,面积为a[i] * (R[i] - L[i])。
利用单调栈维护单调递增的栈,我们可以O(n)求出所有的 i 的 L[i], R[i].

Step3 Code:

#include
#include
using namespace std;
#define ll long long
const int N = 1e5+5;
ll a[N];;
int L[N], R[N], st[N];
int main()
{
    int n;
    while(~scanf("%d", &n) && n)
    {
        for(int i = 1; i <= n; i++)
            scanf("%lld", &a[i]);
        int top = 0;
        for(int i = 1; i <= n; i++)
        {
            while(top && a[st[top-1]] >= a[i]) top--;
            L[i] = (top==0) ? 0 : st[top-1];
            st[top++] = i;
        }
        top = 0;
        for(int i = n; i >= 1; i--)
        {
            while(top && a[st[top-1]] >= a[i]) top--;
            R[i] = (top==0) ? (n+1) : st[top-1];
            st[top++] = i;
        }
        ll ans = 0;
        for(int i = 1; i <= n; i++)
        {
            ans = max(ans, (ll)(R[i]-L[i]-1)*a[i]);
        }
        printf("%lld\n", ans);
    }
    return 0;
}

你可能感兴趣的:(栈和队列)