小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;
}
posted @ 2019-04-16 16:24  ChunhaoMo  阅读(161)  评论(0)    收藏  举报