poj2559 Largest Rectangle in a Histogram(单调栈)

题意

有n个矩形,它们在一条水平线上且宽度都为1,长度分别为a[i]。求其中的最大子矩阵。

思考过程

我们从左往右枚举每一个矩形,第i个矩形依次尝试宽度为1~n-i+1,记录最低高度和最大面积。这个可以实现。
我们发现,其中的很多状态是包含的,导致我们做了很多无用的尝试。
事实上,对于一个相同的高度,我们希望它尽量宽,

题解

单调栈
建立一个单调递增栈,因为一个高度低的潜力更大,所以我们把它压到栈更深的地方。
对于一个大于栈顶的高度,我们直接放到栈顶上,记下这个位置。
如果小于栈顶,就要一直出栈直到大于栈顶的高度。弹出时计算一下以sta[top].h为高,以sta[top].p~i-1为宽的矩形的面积,看看要不要更新ans。

代码

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100010;

int n;
int a[maxn];
struct S
{
    int h,p;//h高度 p位置 
}sta[maxn];int top;

int main()
{
    while(scanf("%d",&n),n!=0)
    {
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        long long ans=0;
        top=0;
        for(int i=1;i<=n;i++)
        {
            int p=i; 
            while(a[i]<=sta[top].h && top!=0)
            {
                ans=max(ans,(long long)sta[top].h*(i-sta[top].p));//计算矩形面积 
                p=sta[top].p;//p记录最远的位置 
                top--;
            }
            sta[++top]=(S){a[i],p};
        }
        while(top!=0)//把所有留在栈内的矩阵计算一下 
        {
            ans=max(ans,(long long)sta[top].h*(n+1-sta[top].p));
            top--;
        }
        printf("%lld\n",ans);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/A_Bright_CH/article/details/81630734
今日推荐