J - Largest Rectangle in a Histogram HDU - 1506

J - Largest Rectangle in a Histogram

HDU - 1506

题目描述:

一个柱形图,求一个贴着x轴的矩形的最大面积。

分析:

可以看出是从一个点向左和右扩张,只要比i高,都可以作为扩张对象。

所以记录L[i],R[i]为i的左边界和右边界。如果暴力i--记为L,i++记为R。会T。

所以进行优化,可以看到,从i向左出发,高度比i大的,一直扩张到最左的记为pos。pos~i的区间左边界L都相同。又由于L[pos]=pos,因为不能再向左扩张。

所以可以直接通过pos和L的关系,跳过pos~i的中间部分。

最后答案就是遍历每个点i:(R[i]-L[i]+1)*a[i]的最大值。

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<sstream>
#include<vector>
#include<stack>
#include<deque>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
const int maxn=1e6+6;
int L[maxn],R[maxn],a[maxn];    
int n;
void init()
{
    memset(L,0,sizeof L);
    memset(R,0,sizeof R);
}
ll cal(int i)
{
    return (R[i]-L[i]+1)*1LL*a[i];
}
int main()
{
    while(1)
    {
        //init();
        scanf("%d",&n);
        if(n==0) break;
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        ll ans=0;
        L[1]=1;
        R[n]=n;
        //左坐标 
        for(int i=2;i<=n;i++)
        {
            int pos=i;
            //向左找到最小的 
            while(pos>1&&a[pos-1]>=a[i]) pos=L[pos-1];
            L[i]=pos;
        }
        //右坐标 
        for(int i=n-1;i>=1;i--)
        {
            int pos=i;
            while(pos<n&&a[pos+1]>=a[i]) pos=R[pos+1];
            R[i]=pos;
        }
        for(int i=1;i<=n;i++)
        {
            //printf("%d:l-%d==r-%d\n",i,L[i],R[i]);
            ll re=cal(i);
            if(re>ans) ans=re;
        }
        printf("%lld\n",ans);
    }   
    return 0;
}

 

猜你喜欢

转载自www.cnblogs.com/studyshare777/p/12548393.html