一二三四五 上山打老虎

CCF-CSP-2013-12-3最大的矩形

链接:http://118.190.20.162/view.page?gpid=T3

思路:
1: 暴力枚举: O(N2)
2: 单调栈 O(N)
代码:

#include<bits/stdc++.h>

using namespace std;
vector<int> ve;
int main (){
    int n,num;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>num;
        ve.push_back(num);
    }
    int manum=0,ans;
    for(int i=0;i<n;i++){
        int ans=1;
        for(int j=i-1;j>=0;j--){
            if(ve[j]<ve[i])break;
            ans++;
        }
        for(int j=i+1;j<n;j++)
            if(ve[i]>ve[j])break;
            else ans++;
        manum=max(manum,ans*ve[i]);
    }
    cout<<manum;
    return 0;
}

单调栈写法:
单调栈相当于利用单调性优化了O(N2)枚举求解每个矩形高度作为最后矩形高度的算法,时间复杂度优化到了O(n)
注意:
1.加入一个新的矩形的时候,如果大于最后一个矩形,则直接加入(维护单调递增),如果相等则加入,而且宽度也置为1(把相等也可以视作大于情况处理),如果小于则弹出前边所有大于当前矩形,并依次计算按照每个弹出的高度作为最后矩形高度的结果,并把记录宽度,最后存储到当前要弹入的宽度中。
2.为了防止最后栈中还有未弹出来计算的元素,最后再加入一个高度为0的矩形。

#include<bits/stdc++.h>

using namespace std;

int main (){
    int n;
    cin>>n;
    vector<int> st(n),wd(n),ve(n+1);
    int ans=0;
    int num,tot=0;
    st[0]=0;
    for(int i=0;i<n;i++)cin>>ve[i];
    ve[n]=0;
    for(int i=0;i<=n;i++){
        num=ve[i];
        if(num>st[tot]){
                st[++tot]=num;
                wd[tot]=1;
        }
        else {
            int w=0;
            while(st[tot]>num){
                w+=wd[tot];
                ans=max(ans,w*st[tot]);
                tot--;
            }
            st[++tot]=num;wd[tot]=w+1;
        }
    }
    cout<<ans;


    return 0;
}


posted @ 2021-04-05 12:53  黒川川  阅读(77)  评论(0)    收藏  举报