类型:单调栈
传送门:>Here<
题意:求一个$01$矩阵中最大子矩形(全是$1$)的面积
解题思路
单调栈的一个经典应用
考虑维护一个数组$p[i][j]$表示$(i,j)$往上最多有多少个连续的$1$。于是问题就转化为上一题的问题了,$p$即为高度,往左右扩散,利用单调栈求即可。总复杂度$O(n^2)$
个人认为,会做这类题的关键还是彻底弄懂上一题
Code
/*By DennyQi 2018.8.18*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
#define r read()
#define Max(a,b) (((a)>(b)) ? (a) : (b))
#define Min(a,b) (((a)<(b)) ? (a) : (b))
using namespace std;
typedef long long ll;
const int MAXN = ;
const int MAXM = ;
const int INF = ;
inline int read(){
int x = ; int w = ; register int c = getchar();
while(c ^ '-' && (c < '' || c > '')) c = getchar();
if(c == '-') w = -, c = getchar();
while(c >= '' && c <= '') x = (x<<) + (x<<) + c - '', c = getchar();return x * w;
}
int N,M,top,ans,cnt; char c[];
int a[][],p[][],h[],w[];
int main(){
scanf("%d %d",&N,&M);
getchar();
for(int i = ; i <= N; ++i){
for(int j = ; j <= M; ++j){
scanf("%s",c);
a[i][j] = (c[] == 'F' ? : );
}
}
for(int i = ; i <= N; ++i){
for(int j = ; j <= M; ++j){
if(a[i][j]){
p[i][j] = p[i-][j] + ;
}
else{
p[i][j] = ;
}
}
}
for(int i = ; i <= N; ++i){
top = ;
for(int j = ; j <= M; ++j){
if(!top || p[i][j] > h[top]){
h[++top] = p[i][j];
w[top] = ;
}
else{
cnt = ;
while(top > && p[i][j] <= h[top]){
cnt += w[top];
ans = Max(ans, h[top] * cnt);
--top;
}
h[++top] = p[i][j];
w[top] = cnt+;
}
}
cnt = ;
while(top > ){
cnt += w[top];
ans = Max(ans, h[top] * cnt);
--top;
}
}
printf("%d", ans * );
return ;
}