• HihoCoder1664 01间隔方阵([Offer收割]编程练习赛40)(DP)


    给定一个NxM的01矩阵,小Hi希望从中找到一个01间隔的子方阵,并且方阵的边长越大越好。  

    例如对于

    0100100
    1000101
    0101010
    1010101
    0101010

    在右下角有一个4x4的01间隔方阵。

    Input

    第一行包含两个整数N和M。  

    以下N行M列包含一个NxM的01矩阵。

    对于30%的数据,1 ≤ N, M ≤ 250

    对于100%的数据,1 ≤ N, M ≤ 1000

    Output

    输出最大的01间隔方阵的边长。

    Sample Input

    5 7  
    0100100
    1000101
    0101010
    1010101
    0101010

    Sample Output

    4

    面积DP。

    加强版:hihocoder1673

    #include<cstdio>
    #include<cstdlib>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    const int maxn=1010;
    char c[maxn][maxn];
    int L[maxn][maxn],H[maxn][maxn];
    int a[maxn][maxn];
    int main()
    {
        int n,m,i,j,ans=0;
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++) scanf("%s",c[i]+1);
        for(i=1;i<=n;i++) L[i][1]=1;
        for(i=1;i<=m;i++) H[1][i]=1;
        for(i=1;i<=n;i++)
          for(j=2;j<=m;j++)
            L[i][j]=c[i][j]==c[i][j-1]?1:L[i][j-1]+1;          //左延伸 
        for(i=1;i<=m;i++)
          for(j=2;j<=n;j++)
            H[j][i]=c[j][i]==c[j-1][i]?1:H[j-1][i]+1;          //上延伸 
        for(i=1;i<=n;i++) 
         for(j=1;j<=m;j++){
             if(i==1||j==1||c[i][j]!=c[i-1][j-1])a[i][j]=1;   //对角线是一样的 
             else {
                a[i][j]=min(a[i-1][j-1]+1,L[i][j]);
                a[i][j]=min(a[i][j],H[i][j]);
             }
             if(a[i][j]>ans) ans=a[i][j];//这一行复制过来的时候被删了。。。
         }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    拷贝构造函数的用法
    虚基类的用法
    函数模板的用法,以及类外定义的注意事项
    怎么学好python?
    树状数组单点更新和区间查询
    线段树的基本操作
    快排算法的实现
    react-redux 中 connect 的常用写法
    ant-design表单处理和常用方法及自定义验证
    ionic 签名、打包
  • 原文地址:https://www.cnblogs.com/hua-dong/p/8052496.html
Copyright © 2020-2023  润新知