Luogu P1169 [ZJOI2007]棋盘制作

这其实归到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;
}
原文地址:https://www.cnblogs.com/cjjsb/p/9016384.html