Largest Rectangle in a Histogram HDU - 1506 解题报告

一道从来没见过的单调栈题目,先来一篇大佬有关于单调栈的详解。

单调栈详解

题目大意:让你选出图表中面积最大的矩形。

思路:在刚看完单调栈的详解后,自己也试了试做这道题,但是仍然没有思路,包括看完题解之后脑子一片混沌,不明白这是怎么和单调栈扯上关系的,反复思考了许多遍代码之后才有了一点心得,在这里与大家分享(具体题目的思路在上面的详解中有)。

首先这道题我们需要先规定一个标准,枚举每个点,只要遇到比自己就要终止,遇到比自己大的就继续迭代。

个人人文单调栈的本质其实就是存取,淘汰,迭代,只要订立一个标准让他去工作就可以。

这里分析这道题的第一个例子(结合下面给出的AC代码):

PS:第一行代表的是左边界,第二行代表的是右边界。

我们直接看数据中的4,他的左边界是2,有边界是4,然后我们在看2是怎么得出的,2代表数组中的位置1所代表的位置,有边界4是数组中位置4所代表的位置,所得出的结果正确。

但是由于我们的平常思维都是想办法确定一个确定位置然后再去分散,所以可能不是很理解,这就是单调栈的迭代问题,这里起作用的就是我们上面所立的标准,凡是比自己小的一律结束然后我们可以发现,自己左右两边的值都大于自己并且最接近自己的值,而自己则是中间的最小值。

(可能介绍的有点乱,但是还是希望自己能多出样例多理解,单调栈十分重要)

下面给出AC代码:


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+100;
stack<int> s;
ll a[maxn],l[maxn],r[maxn];


int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;

        memset(l,0,sizeof(l));
        memset(r,0,sizeof(r));

        for(int i=0; i<n; i++)  scanf("%lld",&a[i]);

        while(!s.empty()) s.pop();

        for(int i=0;i<n;i++)
        {
            while(!s.empty()&&a[s.top()]>=a[i]) s.pop();

            if(s.empty()) l[i]=0;
            else l[i]=s.top()+1;

            s.push(i);
        }

        while(!s.empty()) s.pop();

        for(int i=n-1;i>=0;i--)
        {
            while(!s.empty()&&a[s.top()]>=a[i]) s.pop();

            if(s.empty()) r[i]=n;
            else r[i]=s.top();

            s.push(i);
        }

        for(int i=0;i<n;i++) printf("%d ",l[i]);
        printf("\n");
        for(int i=0;i<n;i++) printf("%d ",r[i]);
        printf("\n");

        ll ans=0;

        for(int i=0;i<n;i++)
        {
           ans=max(ans,a[i]*(r[i]-l[i]));
        }

        printf("%lld\n",ans);



    }

    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值