NewSjf @ 2019-09-13 11:13:28
RT
DP+前缀和的O(n^2)做法
f[i][j]代表以[i][j]为右下角的区域最大的子矩阵
g[i][j]代表以[i][j]为左下角的区域的最大子矩阵
从[i-1][j-1]或[i][j+1]转移过来,如果子矩阵周围全是0(对应前缀和差为0)
但是只有72分,4 5 10WA了
数据太大看不出什么端详
求大佬帮忙改错一下,谢谢了
#include<iostream>
#include<algorithm>
#define MAXN 2600
using namespace std;
bool a[MAXN][MAXN];
int n,m,f[MAXN][MAXN],g[MAXN][MAXN],ans;
int sumx[MAXN][MAXN],sumy[MAXN][MAXN];
bool check1(int x,int y)
{
if(!a[x][y])return false;
int t=f[x-1][y-1];
if(x-t<1||sumx[x-1][y]-sumx[x-t-1][y])return false;
if(y-t<1||sumy[x][y-1]-sumy[x][y-t-1])return false;
return true;
}
bool check2(int x,int y)
{
if(!a[x][y])return false;
int t=g[x-1][y+1];
if(x-t<1||sumx[x-1][y]-sumx[x-t-1][y]!=0)return false;
if(y+t>m||sumy[x][y+t]-sumy[x][y]!=0)return false;
return true;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
cin>>a[i][j];
f[i][j]=a[i][j];
g[i][j]=a[i][j];
sumx[i][j]=sumx[i-1][j]+a[i][j];
sumy[i][j]=sumy[i][j-1]+a[i][j];
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(check1(i,j))f[i][j]=max(f[i][j],f[i-1][j-1]+1);
if(check2(i,j))g[i][j]=max(g[i][j],g[i-1][j+1]+1);
ans=max({ans,g[i][j],f[i][j]});
}
cout<<ans<<endl;
}
0 0 0 1
0 0 1 0
0 1 0 1
1 0 0 0
by 18Michael @ 2022-03-03 20:49:12
@NewSjf 给组数据
4 4
1 0 0 1
0 0 1 0
0 1 0 1
1 0 0 0
输出是 3。