51nod 1102 面积最大的矩形【单调栈、预处理】

本文介绍了一种使用单调栈解决求最大矩形面积问题的方法。通过维护一个递减的栈来快速找到以每个元素为高度的最大矩形宽度,从而得出最大矩形面积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1102

题意:

这里写图片描述

分析:

这题及得好像在哪做过QAQ,很快就水掉了,
刚开始想的是枚举每个ai,然后向两边 找大于等于ai的最大范围Li和Ri,更新答案ans=max(ans,(R[i]-L[i]+1)*ai)。很容易想到预处理Li和Ri,因为if(a[i-1]>=a[i])那么L[i]至少是L[i-1],求R[i]同理。时间复杂度最多O(nlogn)
叙述的不清楚,还是看这篇吧:http://blog.csdn.net/queuelovestack/article/details/52326276

看到标签是单调栈。维护一个递减的栈,栈中保存对应ai的下标,如果ai>栈顶元素,那么直接放入栈顶。否则,一直弹栈,知道栈顶元素小于ai为止,那么此时弹出的元素个数都是比栈顶元素大的,也就是可以组合矩形,这样的话就可以更新最大值了。
需要注意的细节是,因为栈中保存的是递减的,所以相同值得元素保存最小的那个位置就行了。
为了最后一次把所有的值都计算,最后把-1压栈在计算下即可。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e4+9;
ll a[N];
int main() {
    int n;
    ll ans=0;
    stack<int>s;
    scanf("%d",&n);
    while(!s.empty()) s.pop();
    for(int i=0; i<n; i++)
        scanf("%lld",&a[i]);
    a[n]=-1;
    for(int i=0; i<=n; i++) {
        if(s.empty()||a[i]>a[s.top()]) {
            s.push(i);
        } else if(a[i]<a[s.top()]) {
            int t=i;
            while(!s.empty()&&a[i]<a[s.top()]) {
                ans=max(ans,(i-s.top())*a[s.top()]);
                t=s.top();
                s.pop();
            }
            s.push(t);
            a[t]=a[i];
        }
    }
    printf("%lld\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值