题意:
求最大子矩阵的面积,子矩阵每一列满足从上往下递增。
思路:
将矩阵转换成0/1矩阵,1表示这个数比上面的那个数大,0就是小,转换成0/1矩阵后用一个for循环套一个单调栈就可以解出。for循环就是更新当前状态每列矩形的高度,单调栈就是求每一部分的最大面积。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#include <unordered_map>
#include <unordered_set>
#define ll long long
#define PI 3.1415926
#define lowbit(x) ((~x+1)&x)
#define inf 0x3f3f3f
using namespace std;
const int N=2e3+10;
int a[N][N],st[N][N],h[N];
int main() {
int t;
int n,m;
scanf("%d",&t);
while(t--) {
scanf("%d%d",&n,&m);
int s[N]={0},w[N];
for(int i=1; i<=m; i++) st[n][i] = 1;
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
scanf("%d",&a[i][j]);
if(i!=1&&a[i][j]>=a[i-1][j]) st[i][j] = 1;
else if(i!=1&&a[i][j]<a[i-1][j]) st[i][j]=0;
}
}
int ans=0;
for(int i=1; i<=n; i++) {
for(int j=1; j<=m; j++) {
if(!st[i][j]) h[j] = 1;
else h[j]++;
}
h[m+1] = 0;
int p=0;
for(int j=1; j<=m+1; j++) {
if(h[j]>s[p]) {
s[++p] = h[j];
w[p] = 1;
}
else {
int width = 0;
while(s[p]>h[j]) {
width+=w[p];
ans = max(ans,width*s[p]);
p--;
}
s[++p] = h[j];
w[p] = width+1;
}
}
}
printf("%d\n",ans);
}
return 0;
}