先膜拜这位大犇的解法:
具体做法:
1. 因为要求0,1交替我们先在读入时做if((i+j)%2==0)a[i][j]^=1;
之后我们只需求最大的全0或全1矩阵/正方形即可。
2. 我们用i枚举0/1,然后类似简单DP的方法求出j行及以上第k列有f[]个连续0/1。
3. 用R[]/L[]记录最右边/最左边大于等于f[]的列数。
4. 最后判断改变ans,anss的值即可。
以下是代码菌(≧▽≦)/
/**************************************************************
Problem: 1057
User: fantasticwtl
Language: C++
Result: Accepted
Time:2612 ms
Memory:16532 kb
****************************************************************/
#include <cstdio>
#include <cstring>
using namespace std;
int n,m,ans,anss,a[2005][2005],f[2005],L[2005],R[2005];
void LG ()
{
for(int i=0;i<=1;i++){
memset(f,0,sizeof(f));
for(int j=1;j<=n;j++){
for(int k=1;k<=m;k++)
if(a[j][k]==i)f[k]=f[k]+1;else f[k]=0;//第二步
for(int k=1;k<=m;k++){
L[k]=k;
while(L[k]-1>=1&&f[L[k]-1]>=f[k])L[k]=L[L[k]-1];
}
for(int k=m;k>=1;k--){
R[k]=k;
while(R[k]+1<=m&&f[R[k]+1]>=f[k])R[k]=R[R[k]+1];
}//第三步
for(int k=1;k<=m;k++){
int s=f[k]*(R[k]-L[k]+1),g=R[k]-L[k]+1;
int ss=f[k]>g?g:f[k];
ss=ss*ss;
if(s>ans)ans=s;
if(ss>anss)anss=ss;
}//第四步
}
}
}
int main ()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++){
scanf("%d",&a[i][j]);
if((i+j)%2==0)a[i][j]^=1;//第一步
}//输入部分
LG ();
printf("%d\n%d\n",anss,ans);
}