zoukankan      html  css  js  c++  java
  • 洛谷P1736 创意吃鱼法

    题目描述

    回到家中的猫猫把三桶鱼全部转移到了她那长方形大池子中,然后开始思考:到底要以何种方法吃鱼呢(猫猫就是这么可爱,吃鱼也要想好吃法 ^_*)。她发现,把大池子视为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

    【题解】

    这是一道送命题

    状态和转移比较显然,需要注意条件,我开始用前缀和,70分,后来发现不对。。改成预处理注释中

    的内容。我比较懒,于是开了二维。。。空间可以更加优化

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #define max(a, b) ((a) > (b) ? (a) : (b))
     6 #define min(a, b) ((a) < (b) ? (a) : (b))
     7 
     8 const int INF = 0x3f3f3f3f;
     9 const int MAXN = 2500 + 10;
    10 const int MAXM = 2500 + 10;
    11 
    12 inline void read(int &x)
    13 {
    14     x = 0;char ch = getchar(),c = ch;
    15     while(ch < '0' || ch > '9')  c = ch, ch = getchar();
    16     while(ch <= '9' && ch >= '0')x = x * 10 + ch - '0', ch = getchar();
    17     if(c == '-')x = -x;
    18 }
    19 
    20 int g[MAXN][MAXM], dp[MAXN][MAXM], ans, n, m, left[MAXN][MAXM], up[MAXN][MAXM], down[MAXN][MAXM];
    21 
    22 int main()
    23 {
    24     read(n);read(m);
    25     for(register int i = 1;i <= n;++ i)for(register int j = 1;j <= m;++ j) read(g[i][j]);
    26     
    27     memset(left, 0x3f, sizeof(left));
    28     memset(up, 0x3f, sizeof(up));
    29     memset(down, 0x3f, sizeof(down));
    30     //left[i][j]表示i,j向左能到达的非自己最近的1与他的欧几里得距离 
    31     for(register int i = 1;i <= n;++ i)for(register int j = 1;j <= m;++ j)
    32         if(g[i][j - 1])left[i][j] = 1;
    33         else left[i][j] = left[i][j - 1] + 1; 
    34     //up[i][j] 表示i,j向上能到达的非自己最近的1与他的欧几里得距离
    35     for(register int j = 1;j <= m;++ j)for(register int i = 1;i <= n;++ i)
    36         if(g[i - 1][j])up[i][j] = 1;
    37         else up[i][j] = up[i - 1][j] + 1;
    38     //down[i][j] 表示i,j向下能到达的非自己最近的1与他的欧几里得距离
    39     for(register int j = 1;j <= m;++ j)for(register int i = n;i >= 1;-- i)
    40         if(g[i + 1][j])down[i][j] = 1;
    41         else down[i][j] = down[i + 1][j] + 1;
    42     
    43     for(register int i = 1;i <= n;++ i)for(register int j = 1;j <= m;++ j)
    44         if(!g[i][j])dp[i][j] = 0;
    45         else dp[i][j] = min(dp[i - 1][j - 1], min(left[i][j] - 1, up[i][j] - 1)) + 1, ans = max(ans, dp[i][j]);
    46     
    47     memset(dp, 0, sizeof(dp));
    48     for(register int i = n;i >= 1;-- i)for(register int j = 1;j <= m; ++ j)
    49         if(!g[i][j])dp[i][j] = 0;
    50         else dp[i][j] = min(dp[i + 1][j - 1], min(left[i][j] - 1, down[i][j] - 1)) + 1, ans = max(ans, dp[i][j]);
    51     printf("%d
    ", ans);
    52     return 0;
    53 }
    洛谷P1736 创意吃鱼法
  • 相关阅读:
    Java实现 蓝桥杯 算法提高 特等奖学金(暴力)
    Java实现 蓝桥杯 算法提高 特等奖学金(暴力)
    Java实现 蓝桥杯 算法提高 GPA(暴力)
    Java实现 蓝桥杯 算法提高 GPA(暴力)
    Java实现 蓝桥杯 算法提高 GPA(暴力)
    Java实现 蓝桥杯 算法提高 套正方形(暴力)
    Java实现 蓝桥杯 算法提高 套正方形(暴力)
    第一届云原生应用大赛火热报名中! helm install “一键安装”应用触手可及!
    云原生时代,2个方案轻松加速百万级镜像
    Knative 基本功能深入剖析:Knative Serving 自动扩缩容 Autoscaler
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/7353982.html
Copyright © 2011-2022 走看看