7 条题解

  • 0
    @ 2024-1-27 11:46:22

    因为对于一个高度 hih_i, 我们往左边一直以这个高度延伸,直到不行,再往右边进行一样的操作

    那么什么时候不行呢,就是当想要继续延伸的块高度比hih_i

    左边的极限就是 hl  (hl1<hi)h_l \ \ (h_{l-1}<h_i) 右边的极限就是 hr  (hr+1<hi)h_r \ \ (h_{r+1}<h_i)

    那么以 ii 为原点往左右两边延伸的最大面积就是(rl+1)hi(r-l+1)*h_i

    我们使用单调栈即可求出 l1l-1r+1r+1,我们暂时记为 ans1ans1ans2ans2

    那么上述提到的面积就是(ans2ans11)hi(ans2-ans1-1)*h_i 自己推导一下就知道了


    AC CODE

    #include <bits/stdc++.h> 
    using namespace std;
    const long long N = 1e5+10,INF = 0x3f3f3f3f;
    long long a[N],ans[N],ans2[N],st[N],n,top,res,tmp;
    void calc1(){
    	for(long long i = 1; i <= n; i++){
    		while(top>0&&a[i]<=a[st[top]])top--;
    		ans[i]=st[top];st[++top]=i;
    	}//单调栈模版,但是>=改成<=以达到效果 
    }
    void calc2(){
    	for(long long i = n; i >= 1; i--){
    		while(top>0&&a[i]<=a[st[top]])top--;
    		ans2[i]=st[top];st[++top]=i;
    	}//单调栈模版,但是>=改成<=以达到效果 
    }
    void solve(){
    	cin >> n;
    	if(n==0)exit(0);
    	top = 0, res = 0, a[0]=a[n+1]=-INF;
    	for(long long i = 1; i <= n; i++)cin >> a[i];
    	top = 0;st[++top]=0;calc1();//计算ans1 
    	top = 0;st[++top]=n+1;calc2();//计算ans2 
    	for(long long i = 1; i <= n; i++)res = max(res,(ans2[i]-ans[i]-1)*a[i]);
    	cout << res << '\n';
    }
    signed main(){
    	while(1+1==2)solve();
    	return 0;
    }//完美30行结束 
    

    信息

    ID
    42
    时间
    1000ms
    内存
    128MiB
    难度
    5
    标签
    递交数
    221
    已通过
    89
    上传者