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();
}
}