0
点赞
收藏
分享

微信扫一扫

杭电多校一

左手梦圆 2022-03-27 阅读 157
c++

Maximal submatrix

这道题的题意就是求已知矩阵的最大单调不下降矩阵,比赛中只会用暴力的方法,tle了
看了题解,说是转化为01矩阵,然后用悬线法求出,太菜了,表示没听过,网上学了一波,先将悬线向上拓展到最大,然后尽量向左右拓展,
具体运用这道题的话就是,先得出每个点的深度(指从上而下目前得不下降长度),对于每一行的点,从左至右,求出该点在深度最大的情况下的左右宽度,相乘则得出最大矩阵个数.

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int N=2*1e3+5;
ll v[N][N],h[N],k[N][N],l[N],r[N];
ll n,m;
ll ans;
void solve() {
    ans=0 ;
    scanf("%d %d",&n,&m);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m; j++) {
            scanf("%d",&v[i][j]);
        }
    for(int i=n; i>=1; i--) {
        for(int j=1; j<=m; j++) {
            if(i==1)v[i][j]=0;
            else {
                if(v[i][j]-v[i-1][j]>=0)v[i][j]=0;
                else v[i][j]=1;
            }
        }
    }
//    for(int i=1; i<=n; i++){
//        for(int j=1; j<=m; j++) {
//            cout<<v[i][j]<<" ";
//        }
//        cout<<endl;
//    }
        
    for(int i=1;i<=m;i++){
        h[i]=1;
    }
    for(int i=2; i<=n; i++){
        for(int j=1; j<=m; j++) {
            if(v[i][j]==0)h[j]+=1;
            else h[j]=1;
            l[j]=r[j]=j;
        }
        h[0]=0;
        h[m+1]=0;
        for(int j=1;j<=m;j++){
            while(h[l[j]-1]>=h[j])l[j]=l[l[j]-1];
        }
        for(int j=m;j>=1;j--){
            while(h[r[j]+1]>=h[j])r[j]=r[r[j]+1];
        }
        for(int j=1;j<=m;j++){            
            ans=max(ans,h[j]*(r[j]-l[j]+1));
//        cout<<l[j]<<"  "<<r[j]<<endl; 
        }
//        cout<<"*"<<endl;
//        cout<<ans<<endl;
    }
    cout<<ans<<endl;
        
}

int main() {
    ll t;
    cin>>t;
    while(t--) {
        solve();
    }
}
举报

相关推荐

0 条评论