题目描述:
一个柱形图,求一个贴着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; }