A. All-one Matrices
题意:求不能再增大的最大子矩阵个数
思路:单调栈问题。我们看下面一个简单的图就可以知道当第i列右边的高度高于i时,则i列的单元块会被包含在其中,而当高度小于时则不会被包含。
对于栈中每一个Up值,还需要维护一个其向左能拓展的最远位置Left
每当有元素退栈时,设退栈元素为 (Up, Left),那么可以得到一个全1矩阵 (i-Up+1, Left) - (i, j)
再判断这个矩阵能否会被更大的矩形嵌套
code:
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
using namespace std;
const int maxn=3005;
char a[maxn][maxn];
int up[maxn][maxn];
stack<pii> s;
int n,m;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%s",a[i]+1);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++)
up[i][j] = a[i][j]-'0'?up[i-1][j]+a[i][j]-'0':0;
}
int ans=0;
for(int i=1;i<=n;i++){
int tmp=-1;
while(!s.empty()) s.pop();
for(int j=1;j<=m+1;j++){
int pos=j;
while(!s.empty()&&s.top().first>up[i][j]){
if(s.top().second<=tmp) ans++;
pos=s.top().second;
s.pop();
}
if(!up[i+1][j]) tmp=j;
if(up[i][j]&&(s.empty()||s.top().first<up[i][j])) s.push(make_pair(up[i][j],pos));
}
}
printf("%d
",ans);
}