zoukankan      html  css  js  c++  java
  • [ZJOI2007]棋盘制作

    悬线法,用来解决给定矩阵中满足条件的最大子矩阵。

    首先对于矩阵中每一个点,分别向左向右维护合法的最大范围。

    之后对于每个点,与上一排比较,如果和它上方的点满足条件,就取两排中包含这两个点的最大横区间,最大纵区间递归+1.

    代码如下

    #include<cstdio>
    #include<iostream>
    #define N 2010
    using namespace std;
    int le[N][N],ri[N][N],up[N][N],mp[N][N],ans1,ans2;
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                scanf("%d",&mp[i][j]);
                le[i][j]=ri[i][j]=j;
                up[i][j]=1;
            }
        }
        for(int i=1;i<=n;i++)
            for(int j=2;j<=m;j++)
                if(mp[i][j]!=mp[i][j-1])
                    le[i][j]=le[i][j-1];
        for(int i=1;i<=n;i++)
            for(int j=m-1;j>=1;j--)
                if(mp[i][j]!=mp[i][j+1])
                    ri[i][j]=ri[i][j+1];
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                if(i>1&&mp[i][j]!=mp[i-1][j])
                {
                    le[i][j]=max(le[i][j],le[i-1][j]);
                    ri[i][j]=min(ri[i][j],ri[i-1][j]);
                    up[i][j]=up[i-1][j]+1;
                }
                int a=ri[i][j]-le[i][j]+1;
                int b=min(a,up[i][j]);
                ans1=max(ans1,b*b);
                ans2=max(ans2,a*up[i][j]);
            }
        printf("%d
    %d",ans1,ans2);
        return 0;
    }
            
  • 相关阅读:
    JS笔记009
    JS笔记008
    JS笔记007
    JS笔记006
    JS笔记005
    JS笔记004
    JS笔记003
    JS笔记001
    CSS3笔记012
    expdp SYNONYM of publick and schema owner
  • 原文地址:https://www.cnblogs.com/charlesss/p/10597304.html
Copyright © 2011-2022 走看看