• 洛谷1736创意吃鱼法


    题目背景

    感谢@throusea 贡献的两组数据

    题目描述

    回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*)。她发现,把大池子视为01矩阵(0表示对应位置无鱼,1表示对应位置有鱼)有助于决定吃鱼策略。

    在代表池子的01矩阵中,有很多的正方形子矩阵,如果某个正方形子矩阵的某条对角线上都有鱼,且此正方形子矩阵的其他地方无鱼,猫猫就可以从这个正方形子矩阵“对角线的一端”下口,只一吸,就能把对角线上的那一队鲜鱼吸入口中。

    猫猫是个贪婪的家伙,所以她想一口吃掉尽量多的鱼。请你帮猫猫计算一下,她一口下去,最多可以吃掉多少条鱼?

    输入输出格式

    输入格式:

     

    有多组输入数据,每组数据:

    第一行有两个整数n和m(n,m≥1),描述池塘规模。接下来的n行,每行有m个数字(非“0”即“1”)。每两个数字之间用空格隔开。

    对于30%的数据,有n,m≤100

    对于60%的数据,有n,m≤1000

    对于100%的数据,有n,m≤2500

     

    输出格式:

     

    只有一个整数——猫猫一口下去可以吃掉的鱼的数量,占一行,行末有回车。

     

    输入输出样例

    输入样例#1: 复制
    4 6
    0 1 0 1 0 0
    0 0 1 0 1 0
    1 1 0 0 0 1
    0 1 1 0 1 0
    
    输出样例#1: 复制
    3

    说明

    右上角的

    1 0 0
    0 1 0
    0 0 1

    ******DP题,这道题可以看成最大正方形的提高版,求两种扫描线,上面那种是s数组求左面的0个数,下面的那种是求s右面0的个数注意列数加或减1
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<cmath>
     4 #include<algorithm>
     5 using namespace std;
     6 int i,j,n,m,ans = 0,a[2505][2505],f[2505][2505],s[2505][2505],c[2505][2505];
     7 int main()
     8 {
     9     scanf("%d %d",&n,&m);
    10     for(i = 1;i <= n;i++)
    11     {
    12         for(j = 1;j <= m;j++)
    13         {
    14             scanf("%d",&a[i][j]);
    15             if(a[i][j] == 0)
    16             {
    17                 s[i][j] = s[i][j - 1] + 1;
    18                 c[i][j] = c[i - 1][j] + 1;
    19             }
    20             else
    21             {
    22                 f[i][j] = min(f[i - 1][j - 1],min(s[i][j - 1],c[i - 1][j])) + 1;
    23             }
    24             ans = max(ans,f[i][j]);
    25         }
    26     }
    27     memset(f,0,sizeof(f));
    28     memset(s,0,sizeof(s));
    29     for(i = 1;i <= n;i++)
    30     {
    31         for(j = m;j >= 1;j--)
    32         {
    33             if(a[i][j] == 0)
    34             {
    35                 s[i][j] = s[i][j + 1] + 1;
    36                 c[i][j] = c[i - 1][j] + 1;
    37             }
    38             else
    39             {
    40                 f[i][j] = min(f[i - 1][j + 1],min(s[i][j + 1],c[i - 1][j])) + 1;
    41             }
    42             ans = max(ans,f[i][j]);
    43         }
    44     }
    45     printf("%d",ans);
    46     return 0;
    47 }


  • 相关阅读:
    图论集合
    无向连通图求割点(tarjan算法去掉改割点剩下的联通分量数目)
    河南省第七届ACM程序设计大赛总结
    单源最短路(spfa),删边求和
    最小圆覆盖
    二分图最大独立集
    二分图最少路径覆盖
    二分图最少点覆盖
    二分图最大匹配(匈牙利算法)
    最小费用最大流模板题
  • 原文地址:https://www.cnblogs.com/rax-/p/9933700.html
Copyright © 2020-2023  润新知