zoukankan      html  css  js  c++  java
  • 洛谷 P1169||bzoj1057 [ZJOI2007]棋盘制作

    洛谷P1169

    bzoj1057

    这个题目跟最大全0子矩阵是类似的。正方形的话,只要把任意极大子正方形(”极大“定义见后面的”论文“)当成把某个极大子矩形去掉一块变成正方形即可,容易解决。

    解法1:看论文里面的“算法2“(那个是最大全0子矩阵方法,改一下就可以用在此题)

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 using namespace std;
     6 #define fi first
     7 #define se second
     8 #define mp make_pair
     9 #define pb push_back
    10 typedef long long ll;
    11 typedef unsigned long long ull;
    12 typedef pair<int,int> pii;
    13 int n,m;
    14 int a[2010][2010];
    15 int lp[2010][2010],rp[2010][2010];
    16 int lx[2010][2010],rx[2010][2010];
    17 int hei[2010][2010];
    18 int an1,an2;
    19 int calc(int x,int y)
    20 {
    21     return min(x,y)*min(x,y);
    22 }
    23 int main()
    24 {
    25     int i,j;
    26     scanf("%d%d",&n,&m);
    27     for(i=1;i<=n;++i)
    28     {
    29         for(j=1;j<=m;++j)
    30         {
    31             scanf("%d",&a[i][j]);
    32         }
    33     }
    34     for(i=1;i<=n;++i)
    35     {
    36         lx[i][1]=1;
    37         for(j=2;j<=m;++j)
    38             lx[i][j]=(a[i][j]==a[i][j-1])?j:lx[i][j-1];
    39         rx[i][m]=m;
    40         for(j=m-1;j>=1;--j)
    41             rx[i][j]=(a[i][j]==a[i][j+1])?j:rx[i][j+1];
    42     }
    43     for(i=1;i<=n;++i)
    44     {
    45         for(j=1;j<=m;++j)
    46         {
    47             if(i!=1&&a[i][j]!=a[i-1][j])
    48             {
    49                 hei[i][j]=hei[i-1][j]+1;
    50                 lp[i][j]=max(lp[i-1][j],lx[i][j]);
    51                 rp[i][j]=min(rp[i-1][j],rx[i][j]);
    52             }
    53             else
    54             {
    55                 hei[i][j]=1;
    56                 lp[i][j]=lx[i][j];
    57                 rp[i][j]=rx[i][j];
    58             }
    59             //printf("1t%d %d %d %d %d
    ",i,j,hei[i][j],lp[i][j],rp[i][j]);
    60             an1=max(an1,hei[i][j]*(rp[i][j]-lp[i][j]+1));
    61             an2=max(an2,calc(hei[i][j],rp[i][j]-lp[i][j]+1));
    62         }
    63     }
    64     printf("%d
    ",an2);
    65     printf("%d
    ",an1);
    66     return 0;
    67 }
    View Code

    解法2:

    其实最大全0子矩阵还有一种做法:

    枚举每一行作为子矩阵的下底部,求出每一列向上最多扩展几行,然后直接用lightoj1083的做法求解此时的最大子矩阵,取所有方案最大值即可

    改一下也可以用在此题

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<vector>
     5 using namespace std;
     6 #define fi first
     7 #define se second
     8 #define mp make_pair
     9 #define pb push_back
    10 typedef long long ll;
    11 typedef unsigned long long ull;
    12 typedef pair<int,int> pii;
    13 int st[2010],r[2010],l[2010],len;
    14 int an1,an2;
    15 int n,m;
    16 int calc(int x,int y)
    17 {
    18     return min(x,y)*min(x,y);
    19 }
    20 void solve(int *d,int m)
    21 {
    22     int i;
    23     len=0;
    24     for(i=1;i<=m;++i)
    25     {
    26         while(len>0&&d[st[len]]>=d[i])    r[st[len--]]=i-1;
    27         l[i]=st[len];
    28         st[++len]=i;
    29     }
    30     while(len>0)    r[st[len--]]=m;
    31     for(i=1;i<=m;++i)
    32     {
    33         an1=max(an1,d[i]*(r[i]-l[i]));
    34         an2=max(an2,calc(d[i],r[i]-l[i]));
    35     }
    36 }
    37 int a[2010][2010],hei[2010][2010];
    38 int main()
    39 {
    40     int i,j,k;
    41     scanf("%d%d",&n,&m);
    42     for(i=1;i<=n;++i)
    43     {
    44         for(j=1;j<=m;++j)
    45         {
    46             scanf("%d",&a[i][j]);
    47             hei[i][j]=(i==1||a[i][j]==a[i-1][j])?1:hei[i-1][j]+1;
    48         }
    49     }
    50     for(i=1;i<=n;++i)
    51     {
    52         for(j=1;j<=m;j=k+1)
    53         {
    54             k=j;
    55             while(k+1<=m&&a[i][k+1]!=a[i][k])    ++k;
    56             //printf("1t%d %d %d
    ",i,j,k);
    57             solve(hei[i]+j-1,k-j+1);
    58         }
    59     }
    60     printf("%d
    ",an2);
    61     printf("%d
    ",an1);
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    VirtualBox 给虚拟机绑定IP
    【转】 wget 命令用法详解
    [转]python -m SimpleHTTPServer
    longene QQ 安装目录
    查看mininet交换机中的流表
    aircrack-ng 字典破解WPA / WPA2
    Win7 64 安装Visual Studio 2010和SQL Server 2008 R2
    Floodlight 防火墙是如何起作用的
    小米2000万买域名mi.com
    Windows JDK环境变量的配置
  • 原文地址:https://www.cnblogs.com/hehe54321/p/9853269.html
Copyright © 2011-2022 走看看