小A的柱状图

链接

[https://ac.nowcoder.com/acm/contest/549/H]

题意

[]

分析

很显然你必须找到该高度下往左右找到第一个高度比该位置小的。这个区间的宽*该高度。就当前能取到的最多面积
后面就枚举每个高度,很多人用单调栈写了。由于数据水过了其实那是错误的做饭。
比如3
1 1 1
5 5 5
他们会得到0而不是15
我就前后递归找吧具体看代码

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+10;
ll h[N],pre[N],suf[N],sum[N];
//pre[i]表示该位置往前第一个小于h[i]的位置
//suf[i]就和pre相反的 
int main(){
    int n; ll x;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%lld",&x); sum[i]=sum[i-1]+x;
    }
    for(int  i=1;i<=n;i++) scanf("%lld",&h[i]);
    for(int i=1;i<=n;i++){
        if(h[i-1]<h[i]) pre[i]=i-1;
        else{
            int t=pre[i-1];
            while(1){
                if(h[t]<h[i]){
                    pre[i]=t; break;
                }
                t=pre[t];
            }
        }
    }
    for(int i=n;i>=1;i--){
        if(h[i+1]<h[i]) suf[i]=i+1;
        else{
            int t=suf[i+1];
            while(1){
                if(h[t]<h[i]) {
                    suf[i]=t; break;
                }
                t=suf[t];
            }
        }
    }
    ll ans=0;
    for(int i=1;i<=n;i++)
        ans=max(ans,h[i]*(sum[suf[i]-1]-sum[pre[i]]));
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/mch5201314/p/10717976.html