常用技巧:单调栈

通过单调栈,可以将一些题目从O(n2)降到O(n),不需要枚举,扫描一遍将之前的结果存到栈中,处理当前位置时从栈中获取之前的信息,并将当前位置存入栈中。典型模型是求最大矩阵:POJ2559

#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;
int n;
int h[100005],l[100005],r[100005],st[100005];
int main(){
    while(scanf("%d",&n)!=EOF){
        if(n==0) break;
        for(int i=1;i<=n;i++) scanf("%d",&h[i]);
        int t=0;
        for(int i=1;i<=n;i++){
            while(t>0&&h[i]<=h[st[t-1]]) t--;
            if(t==0) l[i]=1;
            else l[i]=st[t-1]+1;
            st[t++]=i;
        }

        t=0;
        for(int i=n;i>=1;i--){
            while(t>0&&h[i]<=h[st[t-1]]) t--;
            if(t==0) r[i]=n+1;
            else r[i]=st[t-1];
            st[t++]=i;
        }

        ll ans=0;
        for(int i=1;i<=n;i++){
            ans=max(ans,(ll)h[i]*(r[i]-l[i]));
        }
        printf("%lld\n",ans);
    }
}

POJ3494,求最大全1子矩阵。可以分行处理,根据当前位置上的情况,决定在当前位置的高度。h[j]=map[i][j]==0?0:h[j-1]+1,那么就成为一个在当前行上求最大矩形面积的问题。类似压行的思想还有求最大子矩阵和的问题,把每列上的数累积求和,在每行上解决最大子段和问题即可。

#include<stdio.h>
#include<algorithm>
using namespace std;
int m,n,num[2005][2005],h[2005],l[2005],r[2005],st[2005];
int main(){
    while(scanf("%d%d",&m,&n)!=EOF){
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                scanf("%d",&num[i][j]);
            }
        }

        int ans=0;
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                h[j]=num[i][j]==0?0:h[j]+1;
            }
            int t=0;
            for(int j=1;j<=n;j++){
                while(t>0&&h[j]<=h[st[t-1]]) t--;
                if(t==0) l[j]=1;
                else l[j]=st[t-1]+1;
                st[t++]=j;
            }
            t=0;
            for(int j=n;j>=1;j--){
                while(t>0&&h[j]<=h[st[t-1]]) t--;
                if(t==0) r[j]=n+1;
                else r[j]=st[t-1];
                st[t++]=j;
            }

            for(int j=1;j<=n;j++){
                ans=max(ans,h[j]*(r[j]-l[j]));
            }
        }
        printf("%d\n",ans);
    }
}

 

posted @ 2020-10-09 15:22  太山多桢  阅读(95)  评论(0编辑  收藏  举报