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; }