A. All-one Matrices 2019牛客暑假多校第八场 (单调栈)

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\n",ans);
}
posted @ 2019-08-18 16:25  Tianwell  阅读(129)  评论(0编辑  收藏  举报