解题思路
参照 Largest Rectangle in a Histogram那道题,这道题算是一个升级版,也就是二维的。
预处理每一列中每个位置上矩阵的高,记为f,设1为一个单位高度,样例如下图:
然后枚举矩阵内每个点,相当于以每一行为低,f[]i[j],为那一位上的高,然后用单调栈算这一行为底能组成的最大的面积
代码
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<cmath>
#include<cstring>
#define ll long long
using namespace std;
ll m,n,s,t,maxn,ans,f[2100][2100],a[2100][2100];
struct c {
ll x,y,w;
} st[2100];
int main() {
while(scanf("%lld%lld",&m,&n)!=EOF) {
ans=0;
for(int i=1; i<=m; i++) {
for(int j=1; j<=n; j++) {
scanf("%lld",&a[i][j]);
}
}
for(int j=1; j<=n; j++) {
for(int i=1; i<=m; i++) {
if(a[i][j]==1)
f[i][j]=f[i-1][j]+1;
else f[i][j]=0;
}
}
for(int i=1; i<=m; i++)
f[i][n+1]=-1;
for(int i=1; i<=m; i++) {
t=0;
memset(st,0,sizeof(st));
for(int j=1; j<=n+1; j++) {
s=0;
while(f[i][j]<=f[st[t].x][st[t].y]&&t>0) {
maxn=f[st[t].x][st[t].y]*(st[t].w+s);
ans=max(ans,maxn);
s+=st[t].w;
t--;
}
st[++t]=(c) {
i,j,s+1};
}
}
printf("%lld\n",ans);
}
}