本文为原创,转载请注明:http://www.cnblogs.com/kylewilson/

题目出处:

https://www.vijos.org/p/1057

题目描述:

给一个N*M的土地,由0和1表示,0表示瑕疵,1表示完好,找出最大的完好的正方形土地?

输入:

输入文件第一行为两个整数n,m(1<=n,m<=1000),接下来n行,每行m个数字,用空格隔开。0表示该块土地有瑕疵,1表示该块土地完好

4 4

0 1 1 1

1 1 1 0

0 1 1 0

1 1 0 1

思路分析:

首先看数据范围,1~1000,存储地图需要O(n*m)的内存空间,空间复杂度可控;再看时间复杂度,遍历所有点为O(n*m);

为什么要先分析空间及时间复杂度呢?因为很多时候,数据规模就决定了算法,如果数据规模为1~1000000000,你还会考虑O(n*n)的算法吗,肯定不会,这种数据一看就知道最优解法为线性复杂度O(n)的算法;

列举如下3处情况:图中彩色方框都为1,白色方框都为0

假设地图中存在一个最大的正方形,则该正方形存在一个右下角P点,且该点为1;

如果当某一个点P(i,j)为0时,则以该点为右下角不存在正方形,所以该点也不可能在最大的正方形中。

不同情况列举:

图P1.1

当P(i,j)=1时,可以看出以P为右下角,最优解由红色边长决定,即以P点为起点,向左连续为1的最多个数,木桶原理

图P1.2

当P(i,j)=1时,可以看出以P为右下角,最优解由紫色边长决定,即以M点为右下角能组成的最大的正方形

图P1.3

当P(i,j)=1时,可以看出以P为右下角,最优解由绿色边长决定,即以P点为起点,向上连续为1的最多个数

则可以建立如下DP公式

设f[i][j]:以点(i,j)为右下角,能组成的最大正方形边长

left[i][j]:以点(i,j)为起点,向左最大连续1的个数,提前初始化

up[i][j]:以点(i,j)为起点,向上最大连续1的个数,提前初始化

f[i][j]=max(f[i-1][j-1]+1, left[i][j], up[i][j])

注:地图为一行或者一列时,提前预处理,方便后面递推

C++源码如下:

github: https://github.com/Kyle-Wilson1/Vijos/tree/master/P1057

#include <iostream>
#include <fstream>
#include <vector> using namespace std; struct Node {
int left, up;
}; int main() {
ifstream cin("a.in");
ofstream cout("a.out"); vector<vector<int>> f(1000, vector<int>(1000, 0));
vector<vector<int>> map(1000, vector<int>(1000, 0));
Node initNode{0, 0};
vector<vector<Node>> node(1000, vector<Node>(1000, initNode)); int n, m, i, j, maxSquare = 0; cin >> n >> m;
//input
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
cin >> map[i][j]; //init left
for (i = 0; i < n; i++)
for (j = 0; j < m; j++) {
if (j == 0) {
if (map[i][j] == 1) {
node[i][j].left = 1;
} else { node[i][j].left = 0; }
} else {
if (map[i][j] == 1) {
node[i][j].left = node[i][j - 1].left + 1;
} else {
node[i][j].left = 0;
}
}
} //init up
for (j = 0; j < m; j++)
for (i = 0; i < n; i++) {
if (i == 0) {
if (map[i][j] == 1) {
node[i][j].up = 1;
} else { node[i][j].up = 0; }
} else {
if (map[i][j] == 1) {
node[i][j].up = node[i - 1][j].up + 1;
} else {
node[i][j].up = 0;
}
}
} auto maxOfTwo = [](int a, int b) { return a > b ? a : b; };
auto minOfThree = [](int a, int b, int c) { return a < b ? a < c ? a : c : b < c ? b : c; }; //dynamic programming
for (i = 0; i < n; i++) {
if (map[i][0] == 1) {
f[i][0] = 1;
maxSquare = 1;
} else f[i][0] = 0;
} for (j = 1; j < m; j++) {
if (map[0][j] == 1) {
f[0][j] = 1;
maxSquare = 1;
} else f[0][j] = 0;
} for (i = 1; i < n; i++)
for (j = 1; j < m; j++) {
f[i][j] = minOfThree(node[i][j].left, node[i][j].up, f[i - 1][j - 1] + 1);
maxSquare = maxOfTwo(f[i][j], maxSquare);
} cout << maxSquare;
cin.close();
cout.close();
return 0;
}

Vijos-P1057题解的更多相关文章

  1. 区间 (vijos 1439) 题解

    [问题描述] 现给定n个闭区间[ai,bi],1<=i<=n.这些区间的并可以表示为一些不相交的闭区间的并.你的任务就是在这些表示方式中找出包含最少区间的方案.你的输出应该按照区间的升序排 ...

  2. vijos题解

    Vijos题解 题库地址:https://vijos.org/p P1001 谁拿了最多奖学金 题意:按照指定要求计算奖学金,直接用if判断即可 #include<iostream> us ...

  3. [题解]vijos & codevs 能量项链

    a { text-decoration: none; font-family: "comic sans ms" } .math { color: gray; font-family ...

  4. [题解]vijos 运输计划

    Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家 ...

  5. 集合删数 (vijos 1545) 题解

    [问题描述] 一个集合有如下元素:1是集合元素:若P是集合的元素,则2 * P +1,4*P+5也是集合的元素,取出此集合中最小的K个元素,按从小到大的顺序组合成一个多位数,现要求从中删除M个数位上的 ...

  6. 洛谷P1057传球游戏题解

    题目 这个题表面上看并不像DP,但是当我们看到方案数时,我们可能会想到什么??? 对,分类加法原理,在每一轮中,每一个点的方案数都要加上这个点左边的方案与右边的方案. 因此我们可以枚举,设一个DP数组 ...

  7. 小胖守皇宫(VIJOS P1144 )题解

    题目描述 huyichen世子事件后,xuzhenyi成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:某些宫殿间可以互相望见.大内保卫森严,三步一岗,五步一哨,每 ...

  8. vijos P1915 解方程 加强版

    背景 B酱为NOIP 2014出了一道有趣的题目, 可是在NOIP现场, B酱发现数据规模给错了, 他很伤心, 哭得很可怜..... 为了安慰可怜的B酱, vijos刻意挂出来了真实的题目! 描述 已 ...

  9. 【BZOJ 1065】【Vijos 1826】【NOI 2008】奥运物流

    http://www.lydsy.com/JudgeOnline/problem.php?id=1065 https://vijos.org/p/1826 好难的题啊TWT ∈我这辈子也想不出来系列~ ...

  10. Vijos1448校门外的树 题解

    Vijos1448校门外的树 题解 描述: 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现 ...

随机推荐

  1. MyBatis:lazy loading

    懒加载的原理 mybatis 会循环处理结果集中返回的每行数据的,在处理之前首先会通过反射调用构造方法来创建 result 对象,结果集中的一行数据最终会映射为一个 result 对象(严格的来说是不 ...

  2. 数据的随机抽取 及 jQuery补充效果(菜单、移动)

    一.数据的随机抽取 都见过那种考试题从很多题中随机抽取几道的试卷吧,现在就要做这样的一个例子:从数据库中随机抽取几条数据出来显示(例如:一百中随机挑选50条) 随机挑选是要有提交数据的,所以肯定是要有 ...

  3. mysql查询进程、导入数据包大小设置

    mysql查询进程.导入数据包大小设置 zoerywzhou@163.com http://www.cnblogs.com/swje/ 作者:Zhouwan 2017-12-27 查询正在执行的进程: ...

  4. [100个改变摄影的伟大观念].(英)玛瑞恩.高清扫描版.pdf

    下载地址  :https://u253469.ctfile.com/fs/253469-229765365

  5. docker入门【1】

    1.拉取镜像 docker pull 镜像名:版本号 例如:docker pull tomcat:7.0 默认会从docker官方镜像库拉取,不指定版本的话版本为latest 拉取后docker im ...

  6. sqlserver 存储过程 删除

    --删除(delete from) CREATE PROCEDURE [dbo].[DeleteMessage] @strtable varchar(),--要删除信息的表名 @strwhere va ...

  7. 解题思路:best time to buy and sell stock i && ii && iii

    这三道题都是同一个背景下的变形:给定一个数组,数组里的值表示当日的股票价格,问你如何通过爱情买卖来发家致富? best time to buy and sell stock i: 最多允许买卖一次 b ...

  8. 598. Range Addition II

    Given an m * n matrixMinitialized with all0's and several update operations. Operations are represen ...

  9. android v4兼容包

    一句话解释android兼容包就是:支持更多的组件,样式更好看了.好粗糙的解释啊! 我们都知道Android一些SDK比较分裂,为此google官方提供了Android Support Library ...

  10. [Maximize ∑arr[i]*i of an Array]

    Given an array of N integers. Your task is to write a program to find the maximum value of ∑arr[i]*i ...