• 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP


    题目背景

    (USACO 5.3.4)

    题目描述

    农夫约翰想要在他的正方形农场上建造一座正方形大牛棚。他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方。我们假定,他的农场划分成 N x N 的方格。输入数据中包括有树的方格的列表。你的任务是计算并输出,在他的农场中,不需要砍树却能够修建的最大正方形牛棚。牛棚的边必须和水平轴或者垂直轴平行。

    EXAMPLE

    考虑下面的方格,它表示农夫约翰的农场,‘.'表示没有树的方格,‘#'表示有树的方格

    1 2 3 4 5 6 7 8

    1 . . . . . . . .

    2 . # . . . # . .

    3 . . . . . . . .

    4 . . . . . . . .

    5 . . . . . . . .

    6 . . # . . . . .

    7 . . . . . . . .

    8 . . . . . . . .

    最大的牛棚是 5 x 5 的,可以建造在方格右下角的两个位置其中一个。

    输入输出格式

    输入格式:

    Line 1: 两个整数: N (1 <= N <= 1000),农场的大小,和 T (1 <= T <= 10,000)有树的方格的数量

    Lines 2..T+1: 两个整数(1 <= 整数 <= N), 有树格子的横纵坐标

    输出格式:

    只由一行组成,约翰的牛棚的最大边长。

    输入输出样例

    输入样例#1:
    8 3
    2 2
    2 6
    6 3
    输出样例#1:
    5

    说明

    题目翻译来自NOCOW。

    USACO Training Section 5.3

    代码

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 int a[1010][1010],N,M;
     8 int f[1010][1010],ans;
     9 
    10 int main(){
    11 //    freopen("01.in","r",stdin);//freopen("01.out","w",stdout);
    12     
    13     scanf("%d%d",&N,&M);
    14     for(int i=1;i<=M;i++){int x,y;scanf("%d%d",&x,&y);a[x][y]=1;}
    15     
    16     for(int i=1;i<=N;i++){
    17         for(int j=1;j<=N;j++){
    18             if(a[i][j]) continue;
    19             else f[i][j]=min(min(f[i-1][j],f[i][j-1]),f[i-1][j-1])+1;
    20             ans=max(f[i][j],ans);
    21         }
    22     }
    23     
    24     printf("%d
    ",ans);
    25     
    26     fclose(stdin);fclose(stdout);return 0;
    27 }

    我就给个思路,两种解法:
    1. DP,用f[i,j]表示以当前格子为右→下角能构成的最大的正方形大小,方程f[i][j]=min(min(f[i-1][j],f[i][j-1]),f[i-1][j-1])+1;代码如上,此处不再赘述;
    2. 二维数组前缀和,可能会超时,可以参见 洛谷P2733 ,跟这道题的区别就是没有区别 ,核心代码如下,如有不理解可参见博客:

    for(int i=1;i<=N;i++){//二维数组前缀和
      for(int j=1;j<=N;j++) sum[i][j]=sum[i][j-1]+int(a[i][j]-'0');
      for(int j=1;j<=N;j++) sum[i][j]+=sum[i-1][j];
    }

    for(int k=2;k<=N;k++)//对边长进行枚举
      for(int i=1;i+k-1<=N;i++)
        for(int j=1;j+k-1<=N;j++)
          if(cal(i,j,i+k-1,j+k-1)==k*k)
            ans=k;

    以下是两道运用前缀和的题目
    [洛谷 P1736 创意吃鱼法](http://www.cnblogs.com/radiumlrb/p/5808527.html)
    [洛谷 P1387 最大正方形 ](http://www.cnblogs.com/radiumlrb/p/5808285.html)

    版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议。转载请注明出处!
  • 相关阅读:
    转:SVN常见问题与解决方法
    Mac OS 下的解压缩软件——The Unarchiver
    Django报错 The serializer field might be named incorrectly and not match any Got AttributeError when attempting to get a value for field `author_for` on serializer `KnownledgeBaseListSerializer`
    Django 生成数据库表时的报错TypeError: __init__() missing 1 required positional argument: 'on_delete'
    webstorm不能中文输入问题
    npm报错This is probably not a problem with npm. There is likely additional logging
    Django 报错no sucn column: OpretionalError
    Python 报错 AttributeError: module 'django.db.models' has no attribute 'SubfieldBase'
    详解Django中Request对象的相关用法
    Python中import, from...import,import...as的区别
  • 原文地址:https://www.cnblogs.com/radiumlrb/p/6052537.html
Copyright © 2020-2023  润新知