2019牛客暑期多校训练营(第八场)A.All-one Matrices(dp)

题意:又是最大01矩阵的模型了 这次要找的是极大0/1矩阵的个数

思路:我们像处理最大01矩阵那样处理一下边界 由于我们上左右已经无法再继续扩展 我们只需要用前缀和记录一下是否可以向下扩展(即判断当前的左右边界的下面是否都有1),

还要用一个标记数组记录一下同一矩阵

#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const int N = 3e3+7;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
typedef long long ll;
const ll mod = 1e7+9;
int n,m;
int h[N][N],sum[N][N],l[N],r[N];
bool jug[N][N];
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++){
            char a; cin>>a;
            if(a=='1') sum[i][j]=sum[i][j-1]+1,h[i][j]=h[i-1][j]+1;
            else sum[i][j]=sum[i][j-1],h[i][j]=0;
        }
    int ans=0;
    for(int i=1;i<=n;i++){
        l[0]=1,r[m+1]=m;
        h[i][0]=h[i][m+1]=-1;
        for(int j=1;j<=m;j++){
            l[j]=j;
            while(h[i][l[j]-1]>=h[i][j])
                l[j]=l[l[j]-1];
        }
        for(int j=m;j>=1;j--){
            r[j]=j;
            while(h[i][r[j]+1]>=h[i][j])
                r[j]=r[r[j]+1];
        }
        for(int j=1;j<=m;j++){
            if(!h[i][j]||jug[l[j]][r[j]]) continue;
            if(sum[i+1][r[j]]-sum[i+1][l[j]-1]!=r[j]-l[j]+1){
                ans++;
                jug[l[j]][r[j]]=1;
            }
        }
        for(int j=1;j<=m;j++) jug[l[j]][r[j]]=0;
    }
    cout<<ans<<endl;
}

猜你喜欢

转载自www.cnblogs.com/wmj6/p/11334923.html