《挑战程序设计竞赛》第一阶段阅读计划

Date Chapter Start Page End Page Finish on Time❓
2020-07-06 2.1 最基础的“穷竭搜索” 26 38 ✔️
2020-07-07 2.2 一往直前!贪心法 39 50
2020-07-08 2.3 记录结果再利用的“动态规划” 51 69
2020-07-09 2.4 加工并存储数据的数据结构 70 90
2020-07-10 2.5 它们其实都是“图” 91 112
2020-07-11 2.6 数学问题的解题窍门 113 124
2020-07-12 2.7 一起来挑战GCJ的题目(1) 125 135

第 2 章 初出茅庐——初级篇

2.1 最基础的“穷竭搜索”

2.1.2 栈

最后进入栈的数据最先被取出(这种行为被叫做 LIFO: Last In First Out,即后进先出)

2.1.3 队列

最初放入的元素最先被取出(这种行为被叫做 FIFO: First In First Out,即先进先出)

2.1.4 深度优先搜索

DFS, Depth-First Search

P30 部分和问题

给定整数 a1,a2,⋯,ana_1, a_2, \cdots, a_na1​,a2​,⋯,an​,判断是否可以从中选出若干数,使它们的和恰好为 k。

#include <bits/stdc++.h>
using namespace std;const int MAX_N = 20 + 5;
int n;
int a[MAX_N];
int k;void input() {scanf("%d", &n);for (int i = 0; i < n; i++) {scanf("%d", &a[i]);}scanf("%d", &k);
}bool dfs(int i, int sum) {if (i == n) {return (sum == k);}if (dfs(i + 1, sum)) {return true;}if (dfs(i + 1, sum + a[i])) {return true;}return false;
}int main() {input();if (dfs(0, 0)) {printf("Yes\n");}else {printf("No\n");}return 0;
}/*
Input:
4
1 2 4 7
13
Output:
YesInput:
4
1 2 4 7
15
Output:
No
*/

从 a1a_1a1​ 开始按顺序决定每个数加或不加,在全部 n 个数都决定后再判断它们的和是不是 k 即可,复杂度是 O(2n)O(2^n)O(2n)。

P32 Lake Counting(POJ No.2386)

const int MAX_N = 100 + 5;
const int MAX_M = 100 + 5;
int n;
int m;
char field[MAX_N][MAX_M];void dfs(int x, int y) {field[x][y] = '.';for (int dx = -1; dx <= 1; dx++) {for (int dy = -1; dy <= 1; dy++) {int nx = x + dx;int ny = y + dy;if (0 <= nx && nx < N && 0 <= ny && ny < M && field[nx][ny] == 'W') {dfs(nx, ny);}}}return;
}void solve() {int res = 0;for (int x = 0; x < N; x++) {for (int y = 0; y < M; y++) {if (field[x][y] == 'W') {dfs(x, y);res++;}}}printf("%d\n", res);
}

从任意的 w 开始,不停地把邻接的部分用 ‘.’ 代替。1 次 DFS 后与初始的这个 w 连接的所有 w 就都被替换成了 ‘.’,因此直到图中不再存在 w 为止,总共进行 DFS 的次数就是答案了。8 个方向共对应了 8 种状态转移,每个格子作为 DFS 的参数至多被调用一次,所以复杂度为 O(8×N×M=O(N×M)O(8 \times N \times M=O(N \times M)O(8×N×M=O(N×M)。

2.1.5 宽度优先搜索

BFS, Breadth-First Search

P34 迷宫的最短路径

// 使用 pair 表示状态时,使用 typedef 会更加方便一些
typedef pair<int, int> P;const int MAX_N = 100 + 5;
const int MAX_M = 100 + 5;// 输入
char maze[MAX_N][MAX_M];
int N, M;
int sx, sy;             // 起点坐标
int gx, gy;             // 终点坐标
int d[MAX_N][MAX_N];    // 到各个位置的最短距离的数组
int dx[4] = { 1, 0, -1, 0 };
int dy[4] = { 0, 1, 0, -1 };int bfs() {for (int i = 0; i < N; i++) {for (int j = 0; j < M; j++) {d[i][j] = INF;}}d[sx][sy] = 0;queue<P> que;que.push(P(sx, sy));while (!que.empty()) {P p = que.front();que.pop();if (p.first == gx && p.second = gy) {break;}for (int i = 0; i < 4; i++) {int nx = p.first + dx[i];int ny = p.second + dy[i];if (0 <= nx && nx < N && 0 <= ny && ny <= M && maze[nx][ny] != '#' && d[nx][ny] == INF) {que.push(P(nx, ny));d[nx][ny] = d[p.first][p.second] + 1;}}}return d[gx][gy];
}

宽度优先搜索按照距开始状态由近及远的顺序进行搜索,因此可以很容易地用来求最短路径、最少操作之类问题的答案。这个问题中,状态仅仅是目前所在位置的坐标,因此可以构造成 pair 或者编码成 int 来表达状态。当状态更加复杂时,就需要封装成一个类来表示状态了。转移的方式为四方向移动,状态数与迷宫的大小是相等的,所以复杂度是 O(4×N×M)=O(N×M)O(4 \times N \times M) = O(N \times M)O(4×N×M)=O(N×M)。

宽度优先搜索中,只要将已经访问过的状态用标记管理起来,就可以很好地做到由近及远的搜索。这个问题中由于要求最短距离,不妨用 d[N][M] 数组把最短距离保存起来。初始时用充分大的常数 INF 来初始化它,这样尚未到达的位置就是 INF,也就同时起到了标记的作用。

因为要向 4 个不同方向移动,用 dx[4]dy[4] 两个数组来表示四个方向向量。这样通过一个循环就可以实现四方向移动的遍历。

宽度优先搜索与深度优先搜索一样,都会生成所有能够遍历到的状态,因此需要对所有状态进行处理时使用宽度优先搜索也是可以的。但是递归函数可以很简短地编写,而且状态的管理也更简单,所以大多数情况下还是用深度优先搜索实现。反之,在求取最短路时深度优先搜索需要反复经过同样的状态,所以此时还是使用宽度优先搜索为好。

宽度优先搜索会把状态逐个加入队列,因此通常需要与状态数成正比的内存空间。反之,深度优先搜索是与最大的递归深度成正比的。一般与状态数相比,递归的深度并不会太大,所以可以认为深度优先搜索更加节省内存。

2.1.6 特殊状态的枚举

虽然生成可行解空间多数采用深度优先搜索,但在状态空间比较特殊时其实可以很简短地实现。比如,C++ 的标准库中提供了 next permutation 这一函数,可以把 n 个元素共 n! 种不同的排列生成出来。又或者,通过使用位运算,可以枚举从 n 个元素中取出 k 个的共 CnkC_n^kCnk​ 种状态或是某个集合中的全部子集等。3.2节将介绍如何利用位运算枚举状态。

2.1.7 剪枝

专栏 栈内存和堆内存

  • 调用函数时,主调的函数所拥有的局部变量等信息需要存储在栈内存区;

  • 利用 new 或者 malloc 进行分配的内存区域被称为堆内存。

  • 栈内存在程序启动时被统一分配,此后不能再扩大。由于这一区域有上限,所以函数的递归深度也有上限。虽然与函数中定义的局部变量的数目有关,不过一般情况下 C 和 C++ 中进行上万次的递归是可以的。在 Java 中,在执行程序时可以用参数指定栈的大小。

  • 全局变量被保存在堆内存区。通常不推荐使用全局变量,但是在程序设计竞赛中,由于函数通常不是那么多,并且常常会有多个函数访问同一个数组,因此利用全局变量就很方便。此外,有时必须要申请巨大的数组,与放置在栈内存上相比,将其放置在堆内存上可以减少栈溢出的危险。同时,通常只需定义满足最大需要的数列大小,但如果再额外定义大一些,能很好地避免粗心导致的诸如忘记保留字符串末尾的’\0’的空间之类的漏洞。

第 1 章 蓄势待发——准备篇

1.1 何谓程序设计竞赛

  • P2 抽签
Page 思想 复杂度
3 4 层循环 O(n4)O(n^4)O(n4)
22 对原数组排序
3 层循环,二分查找 m - a[i] - a[j] - a[k]
O(nlog⁡n)O(n \log n)O(nlogn)
O(n3log⁡n)O(n^3 \log n)O(n3logn)
23 a[i] + a[j] 并排序
两层循环,二分查找 m - a[i] - a[j]
O(n2log⁡n)O(n^2 \log n)O(n2logn)
O(n2log⁡n)O(n^2 \log n)O(n2logn)

1.5 以高效的算法为目标

考虑 O(n2)O(n^2)O(n2) 时间的算法,假设题目描述中的限制条件为 n≤1000n \leq 1000n≤1000,将 n=1000n = 1000n=1000 代入 n2n^2n2 就得到了 100000。在这个数值的基础上,我们就可以结合下表进行判断了。

假设时间限制为1秒

1000000 游刃有余
10000000 勉勉强强
100000000 很悬,仅限循环体非常简单的情况

1.6 轻松热身

  • P16 三角形

《挑战程序设计竞赛》阅读笔记相关推荐

  1. trainer setup_Detectron2源码阅读笔记-(一)Configamp;Trainer

    一.代码结构概览 1.核心部分 configs:储存各种网络的yaml配置文件 datasets:存放数据集的地方 detectron2:运行代码的核心组件 tools:提供了运行代码的入口以及一切可 ...

  2. VoxelNet阅读笔记

    作者:Tom Hardy Date:2020-02-11 来源:VoxelNet阅读笔记

  3. Transformers包tokenizer.encode()方法源码阅读笔记

    Transformers包tokenizer.encode()方法源码阅读笔记_天才小呵呵的博客-CSDN博客_tokenizer.encode

  4. 源码阅读笔记 BiLSTM+CRF做NER任务 流程图

    源码阅读笔记 BiLSTM+CRF做NER任务(二) 源码地址:https://github.com/ZhixiuYe/NER-pytorch 本篇正式进入源码的阅读,按照流程顺序,一一解剖. 一.流 ...

  5. Mina源码阅读笔记(一)-整体解读

    2019独角兽企业重金招聘Python工程师标准>>> 今天的这一节,将从整体上对mina的源代码进行把握,网上已经有好多关于mina源码的阅读笔记,但好多都是列举了一下每个接口或者 ...

  6. “CoreCLR is now Open Source”阅读笔记

    英文原文:CoreCLR is now Open Source 阅读笔记如下: CoreCLR是.NET Core的执行引擎,功能包括GC(Garbage Collection), JIT(将CIL代 ...

  7. QCon 2015 阅读笔记 - 团队建设

    QCon 2015阅读笔记 QCon 2015 阅读笔记 - 移动开发最佳实践 QCon 2015 阅读笔记 - 团队建设 中西对话:团队管理的五项理论和实战 - 谢欣.董飞(今日头条,LinkedI ...

  8. 05《软件需求模式》阅读笔记

    剩下的两个阅读笔记写第二部分.各类需求模式,共八个领域和它的需求模式,这一次写前四个. 基础需求模式,它是所有种类的系统都可能需要的一些东西.系统间接口需求模式使用系统间接口需求模式定义被定义的系统和 ...

  9. [置顶] Linux协议栈代码阅读笔记(一)

    Linux协议栈代码阅读笔记(一) (基于linux-2.6.21.7) (一)用户态通过诸如下面的C库函数访问协议栈服务 int socket(int domain, int type, int p ...

  10. 大型网站技术架构:核心原理与案例分析阅读笔记二

    大型网站技术架构:核心原理与案例分析阅读笔记二 网站架构设计时可能会存在误区,其实不必一味追随大公司的解决方案,也不必为了技术而技术,要根据本公司的实际情况,制定适合本公司发展的网站架构设计,否则会变 ...

最新文章

  1. 机房收费系统总结【4】-报错码
  2. 如何应对一直变化的搜索引擎算法?
  3. 论文笔记之:Instance-aware Semantic Segmentation via Multi-task Network Cascades
  4. android的消息处理机制(图文+源码分析)—Looper/Handler/Message[转]
  5. SQL行列转换问题整理
  6. vxworks任务通信机制
  7. ncurses关于颜色系统:start_color(),has_colors(),init_pair(),color_content(),pait_content()
  8. Win + Appium + Android/IOS + Python环境搭建
  9. 【实物】端到端自动驾驶搭建教程(二)附完整资料
  10. bound、frame、position、anchorPoint
  11. c++代码打印爱心图(适用初学者)
  12. 产品读书《产品经理的第二本书》
  13. Android开发之十二:Camera成像原理介绍
  14. java实现简单泡泡屏保动画及点击变实心泡泡
  15. Android那些事!
  16. php框架laravel win10,composer 安装Laravel (win10)
  17. FANUC机器人外部电缆连接示意图(一)
  18. 好看动漫+电影+电视剧分享
  19. streaming mr
  20. MySQL系列教程(五)

热门文章

  1. Delphi 2007 版本号大全
  2. 有什么低价好用的电容笔推荐?ipad可以用的手写笔分享
  3. 计算机应用基础题excel,计算机应用基础专练习题excel.doc
  4. PDF在线阅读开发经验(FlexPaper+SWFTools+SaveAsPDFandXPS)【转】
  5. php_redis配置安装php_redis-5.1.1-7.4-nts-vc15-x64.zip
  6. wps流程图怎么不能添加文字_wps画图怎么添加文字_如何在wps文字中画图
  7. 有道词典词库_最好的免费词典和同义词库程序和网站
  8. Cannot load supported formats: Cannot run program svn: CreateProcess error=2, μ
  9. mysql药品管理_药品管理系统(药库管理)+数据库连接代码
  10. OpenCV图像模糊处理