Largest Rectangle in a Histogram Page53 记忆化/单调栈
方法一: 记忆化
预处理出每个矩形可以拓展到最远的地方(左边界和右边界的极限位置)
如果直接暴力两遍For(1,n)循环,复杂度会到达 ,但是如果处理左边界的时候从左往右遍历,处理右边界的时候从右到左遍历,打个比方,处理右边界时,需要从 开始往右找第一个比它小的高度,发现右边的所有右边界已经处理好了,于是可以直接进行“跳跃”。
代码:
#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);
}
}