这其实归到DP来说实在有点勉强
悬线法的经典问题,改一两句话即可
后来看有人说可以用什么坐标奇偶性然后乱搞一下转化成求最大全0子矩阵(雾)
我还是觉得直接上悬线比较靠谱
与一般的悬线法相似,只要a[i][j]与它边上的点^之后不同就可以转移了
难得的10mins 1A(还记得昨天写悬线法的板子花了1h),实现自己看CODE
CDOE
#include<cstdio>
using namespace std;
const int N=2005;
int a[N][N],h[N][N],l[N][N],r[N][N],ans1,ans2,n,m;
inline char tc(void)
{
static char fl[100000],*A=fl,*B=fl;
return A==B&&(B=(A=fl)+fread(fl,1,100000,stdin),A==B)?EOF:*A++;
}
inline void read(int &x)
{
x=0; char ch=tc();
while (ch<'0'||ch>'9') ch=tc();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=tc();
}
inline int min(int a,int b)
{
return a<b?a:b;
}
inline int max(int a,int b)
{
return a>b?a:b;
}
int main()
{
//freopen("CODE.in","r",stdin); freopen("CODE.out","w",stdout);
register int i,j;
read(n); read(m);
for (i=1;i<=n;++i)
{
for (j=1;j<=m;++j)
{
read(a[i][j]);
if (i!=1) h[i][j]=a[i-1][j]^a[i][j]?h[i-1][j]+1:1; else h[i][j]=1;
if (j!=1) l[i][j]=a[i][j-1]^a[i][j]?l[i][j-1]+1:1; else l[i][j]=1;
}
for (j=m;j>=1;--j)
if (j!=m) r[i][j]=a[i][j+1]^a[i][j]?r[i][j+1]+1:1; else r[i][j]=1;
}
for (i=1;i<=n;++i)
for (j=1;j<=m;++j)
{
if (i!=1&&a[i][j]^a[i-1][j]) l[i][j]=min(l[i][j],l[i-1][j]),r[i][j]=min(r[i][j],r[i-1][j]);
int x=h[i][j],y=l[i][j]+r[i][j]-1;
ans1=max(ans1,min(x,y)*min(x,y)); ans2=max(ans2,x*y);
}
printf("%d
%d",ans1,ans2);
return 0;
}