Maximal submatrix


题面:给定一个图片说明 的矩阵,求其最大子矩阵的面积,要求每列都是不递减的。多组输入。
解析:将给定矩阵转换成0,1矩阵,运用悬线法。用h[ ]数组记录这个点开始的悬线高度,用w[]记录左临界位置的坐标,当遇到悬线高度小于前一悬线,开始更新结果,更新完之后,删除前一个w,继续与之前的比较,使h[w[]]始终递增。
o(n^2),注意用快读或scanf。

代码

#include<bits/stdc++.h>
using namespace std;
int t,n,m;
int h[5050];
int w[5050];
int a[5050][5050],b[5050][5050];
int main(){

    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m); 
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                scanf("%d",&b[i][j]);
                if(i==1) a[i][j]=0;
                else a[i][j]=(b[i][j]>=b[i-1][j]);
            }
        }
    for(int i=1;i<=m;i++) h[i]=0;
        int ans=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++)
        {
            if(a[i][j]==0) h[j]=1;
            else h[j]++;
        }
        h[m+1]=0;//使最后一列更新结果
        int tot=0;

        for(int j=1;j<=m+1;j++)
        {
            while(tot&&h[w[tot]]>h[j]){
                ans=max(ans,h[w[tot]]*(j-1-w[tot-1]));
                tot--;

            }
            w[++tot]=j; //左临界的坐标
        }
    }
        printf("%d\n",ans);
    }


    }