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