继续单调栈,感觉已经掌握了,其实很简单嘛,比如银川2019那道做完这个就会了

题意就是给定一个m*n的矩阵,求最大全1子矩阵

做法就是枚举哪一行做底,显然答案就是
$$
\min_{l\le i\le r}{up[i]}*(r-l+1)
$$
其中up的含义是当前为底的情况下第i列能向上扩展的高度

就和上一道做的题目基本一样啦,左一遍右一遍扫就好了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
//by Richard
#include <cstdio>
#include <iostream>
#include <stack>
#define mp make_pair
#define rep(x,y,z) for (int x=(y);(x)<=(z);(x)++)
#define per(x,y,z) for (int x=(y);(x)>=(z);(x)--)
#define lowbit(x) ((x)&(-(x)))
#ifdef DEBUG
#define debugdo(X) X
#define debugndo(X)
#define debugout(X) cout<<(#X)<<"="<<(X)<<endl
#else
#define debugdo(X)
#define debugndo(X) X
#define debugout(X)
#endif // debug
const int inf=0x3f3f3f3f;
using namespace std;
typedef long long LL;
typedef pair<int,int> pairs;
///////////////////////read5.1///////////////////////
template<typename T>
inline void read(T &x){char ch;x=0;bool flag=false;ch=getchar();while (ch>'9'||ch<'0') {if (ch=='-') flag=true;ch=getchar();}while ((ch<='9'&&ch>='0')){x=x*10+ch-'0';ch=getchar();}if (flag) x*=-1;}
template<typename T,typename U>
inline void read(T &x,U &y){read(x);read(y);}
template<typename T,typename U,typename V>
inline void read(T &x,U &y,V &z){read(x);read(y);read(z);}
////////////////variables&functions//////////////////
const int maxn=2222;
int n,m,a[maxn][maxn],up[maxn][maxn],l[maxn],r[maxn];
stack<int> st;
int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
rep(i,1,n)
rep(j,1,m)
read(a[i][j]);
rep(j,1,m)
rep(i,1,n)
{
if (a[i][j]==1) up[i][j]=up[i-1][j]+1;
else up[i][j]=0;
}
rep(i,1,n) up[i][0]=up[i][m+1]=-1;
int ans=0;
rep(i,1,n)
{
rep(j,1,m+1)
{
if (st.empty()||up[i][st.top()]<=up[i][j]) st.push(j);
else
{
while (!st.empty()&&up[i][st.top()]>up[i][j])
{
r[st.top()]=j-1;
st.pop();
}
st.push(j);
}
}
st.pop();
per(j,m,0)
{
if (st.empty()||up[i][st.top()]<=up[i][j]) st.push(j);
else
{
while (!st.empty()&&up[i][st.top()]>up[i][j])
{
l[st.top()]=j+1;
st.pop();
}
st.push(j);
}
}
st.pop();
rep(j,1,m) ans=max(ans,(r[j]-l[j]+1)*up[i][j]);
}
cout<<ans<<endl;
}
return 0;
}