Largest Rectangle in a Histogram Page53 记忆化/单调栈

Largest Rectangle in a Histogram Page53 记忆化/单调栈

方法一: 记忆化
预处理出每个矩形可以拓展到最远的地方(左边界和右边界的极限位置)

如果直接暴力两遍For(1,n)循环,复杂度会到达 O ( n 2 ) O(n^2) ,但是如果处理左边界的时候从左往右遍历,处理右边界的时候从右到左遍历,打个比方,处理右边界时,需要从 p o s i pos_i 开始往右找第一个比它小的高度,发现右边的所有右边界已经处理好了,于是可以直接进行“跳跃”。

代码

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<queue>
#include<map>
#define ll long long
#define pb push_back
#define rep(x,a,b) for (int x=a;x<=b;x++)
#define repp(x,a,b) for (int x=a;x<b;x++)
#define W(x) printf("%d\n",x)
#define WW(x) printf("%lld\n",x)
#define pi 3.14159265358979323846
#define mem(a,x) memset(a,x,sizeof a)
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
const int maxn=2e5+7;
const int INF=1e9;
const ll INFF=1e18;
ll h[maxn],l[maxn],r[maxn];
int n;
int main()
{
    while(~scanf("%d",&n)&&n)
    {
        ll ans=0;h[0]=h[n+1]=-INF;
        rep(i,1,n)scanf("%lld",&h[i]);
        rep(i,1,n)l[i]=r[i]=i;
        rep(i,1,n)
        {
            while(h[l[i]-1]>=h[i])l[i]=l[l[i]-1];
        }
        for (int i=n;i>=1;i--)
        {
            while(h[r[i]+1]>=h[i])r[i]=r[r[i]+1];
        }
        rep(i,1,n)ans=max(ans,(r[i]-l[i]+1)*h[i]);
        WW(ans);
    }
    return 0;
}





方法二: 单调栈

细节在蓝书上

贴一下自己写的代码

代码

#pragma GCC optimize(1)
#pragma GCC optimize(2)
#pragma GCC optimize(3,"Ofast","inline")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<queue>
#include<map>
#define ll long long
#define pb push_back
#define rep(x,a,b) for (int x=a;x<=b;x++)
#define repp(x,a,b) for (int x=a;x<b;x++)
#define W(x) printf("%d\n",x)
#define WW(x) printf("%lld\n",x)
#define pi 3.14159265358979323846
#define mem(a,x) memset(a,x,sizeof a)
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
using namespace std;
const int maxn=2e6+7;
const int INF=1e9;
const ll INFF=1e18;
ll a[maxn],n;
struct node
{
    ll x,w;
}tmp;
stack<node> S;
int main()
{
    while(~scanf("%lld",&n)&&n)
    {
        ll ans=0;while(!S.empty())S.pop();
        rep(i,1,n)scanf("%lld",&a[i]);a[n+1]=0;
        rep(i,1,n+1)
        {
            if (S.empty())
            {
                tmp.w=1;
                tmp.x=a[i];
                S.push(tmp);
            }
            else if (a[i]>S.top().x)
            {
                tmp.w=1;
                tmp.x=a[i];
                S.push(tmp);
            }
            else
            {
                ll width=0;
                while(!S.empty())
                {
                    if (S.top().x>a[i])
                    {
                        width+=S.top().w;
                        ans=max(ans,width*S.top().x);
                        S.pop();
                    }
                    else break;
                }
                tmp.x=a[i];
                tmp.w=width+1;
                S.push(tmp);
            }
        }
        WW(ans);
    }
}
发布了125 篇原创文章 · 获赞 8 · 访问量 9104

猜你喜欢

转载自blog.csdn.net/w_udixixi/article/details/105021393