1 solutions

  • 0
    @ 2024-11-2 11:27:17

    需要运用单调栈的思想,我们从左往右一个个的看矩形。矩形面积就是宽度*高度,

    如果现在右边新进来的这个矩形的高度小于左边原有的,那么接下来对于右边再继续进入的矩形,因为刚刚进入了一个较低的矩形,左边原有的较高的矩形的高出来的部分面积相当于无效了。右边后续进入的的新矩形无法继续使用前面较高的部分的面积。(因为刚刚新进入的较低的矩形打断了后续矩形对前边原有的矩形更高部分的使用)。

    那么我们从头开始循环每一个矩形,一旦遇到较低的矩形a[i],就向前找一个不低于a[i]的矩形,在途中遇到的较高的矩形的高出来的部分都是无效的,但是高度在a[i]以内的部分还是有效的,因此只需要把高出来的部分砍去,把途中遇到的矩形删除,加上一个新的矩形,是高度为a[i],宽度是删除的矩形的累计宽度,就达到了砍去高于a[i]部分的高度的效果。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int N = 1e5+11;
    
    int n, p;
    ll a[N], s[N], w[N]; 
    
    void work(){
    	int p = 0;
    	ll ans = 0;
    	a[n+1] = a[0];
    	for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    	
    	for(int i=1;i<=n+1;i++){
    		if(a[i] > s[p]){
    			w[++p] = 1;
    			s[p] = a[i];
    		}else{
    			int x = 0;
    			while(a[i] < s[p]){
    				x += w[p];
    				ans = max(ans, s[p] * x);
    				p --;
    			} s[++p] = a[i]; w[p] = x + 1;
    		}
    	} printf("%lld\n",ans);
    }
    
    int main(){
    	while(cin>>n) if(n) work(); else return 0;
    }
    
    
    // ^_^
    
    • 1

    Information

    ID
    524
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    9
    Tags
    (None)
    # Submissions
    12
    Accepted
    5
    Uploaded By