![](https://img-blog.csdnimg.cn/20190927151132530.png?x-oss-process=image/resize,m_fixed,h_224,w_224)
紫书学习
文章平均质量分 78
对紫书的学习和自己的一些见解
酉鬼2333
摆摆
展开
-
11.4 网络流初步
11.4 网络流初步网络流是一个适用范围相当广的模型,相关的算法也非常多。这里我们开始初步(注意是初步)了解这类问题。百度百科的介绍如下hhhh:网络流(network-flows)是一种类比水流的解决问题方法,与线性规划密切相关。网络流的理论和应用在不断发展,出现了具有增益的流、多终端流、多商品流以及网络流的分解与合成等新课题。网络流的应用已遍及通讯、运输、电力、工程规划、任务分派、设备更新以及计算机辅助设计等众多领域。还是直接看问题吧hhhh。11.4.1 最大流问题假设需要把一些物体从结原创 2021-10-02 05:43:11 · 230 阅读 · 0 评论 -
11.3 最短路问题
11.3 最短路问题第九章我们介绍过无权和带权DAG上的最短路最长路问题。这里给图上加上环。11.3.1 Dijkstra 算法Dijkstra算法适用于边权为正的情况,它可用于计算正权图上的单源最短路(就是从单个源点出发,到所有节点的最短路),该算法同时适用于有向图和无向图://初始化所有的结点为未标记,设d[0]=0,其他d[i]=INF//循环n次{// 在所有未标号的结点,选出d值最小的结点x// 给结点x标记,对从x除法的边(x,y),更新d[y]=min{d[y],d[x]+w(原创 2021-09-20 05:40:31 · 283 阅读 · 0 评论 -
11.2 最小生成树
11.2 最小生成树主要就是学习求最小生成树的两个算法和做例题,算法我在另外一篇博客已经全部介绍过了,直接看例题吧。11.2.2 竞赛题目选解11-2 苗条的生成树 (UVA 1395)给出一个n结点的图,求苗条度(最大边减最小边)尽量小的生成树。分析:这里是讨论边的关系,于是考虑用类似Kruskal(后面简称k法)的方法。k法不仅可以求最小生成树,还可以判断若干条边是否能够在图中构成一个生成树。将边按权值从小到大排序,对于一个连续的边集[E1,E2],如果这些边能够构成一个生成树(用k法判断原创 2021-09-18 21:11:34 · 102 阅读 · 0 评论 -
11.1 再谈树
11.1 再谈树这一章开始,就正式开始介绍一些快捷复杂的算法了。11.1.1 无根树转化为有根树输入一个n个结点的无根树的各条边,并指定一个根节点,要求把该树转化为有根树,输出各个结点的父节点编号。分析:事实上这个问题在前几章就已经提到过了,我们先用vector数组来存储与某个结点连接的点的集合:vector<int>G[maxn];//邻接矩阵,G[i]表示结点i有哪些连通的结点 void read_tree{int u,v; cin>>n; for (int i=原创 2021-09-16 23:05:29 · 69 阅读 · 0 评论 -
10.5 训练参考
先咕咕咕原创 2021-09-15 16:46:30 · 61 阅读 · 0 评论 -
10.4 竞赛题目选讲
10.4 竞赛题目选讲10-22 统计问题 (UVA 1640)给出整数a,b,统计a-b之间的整数(包括a和b),数字0-9分别出现了多少次。分析:a和b的数据范围到108,直接暴力打表的话好像·······勉强也可以?但是dp打表的时候还需要优化一下,如果直接用f[i][p]表示1-i中数字p的个数,时间不会爆(我特地去UVA看了一下时间限制到了3s),空间······4亿个字节,自己体会一下好了。于是我们考虑用数位DP,那什么叫做数位DP,我个人理解就是将一个比较大的整数按一位一位进行分割:原创 2021-09-15 16:44:00 · 100 阅读 · 0 评论 -
10.3 其他数学专题
10.3 其他数学专题10.3.1 递推汉诺塔问题假设有A,B,C3个轴,有n个直径各不相同,从小到大依次编号为1,2······n的圆盘按照上小下大的顺序叠放在A轴上。现要求将这n个圆盘移至B轴上并仍按同样顺序叠放,但圆盘移动时必须遵循下列规则。每次只能移动一个圆盘,它必须位于某个轴的顶部。圆盘可以插在A,B,C的任意一个轴上。任何时刻都不能将一个较大的圆盘压在较小的圆盘之上。分析:这是一个非常简单的问题,学过C语言的,递推那章就是以它为例子介绍的递推的定义。n=1时,直接将A的圆盘放到B原创 2021-09-13 12:28:34 · 147 阅读 · 0 评论 -
10.2 计数与概率基础
10.2 计数与概率基础就是排列组合啦······加法原理做一件事情有n个办法,第i个办法有pi种方案,则一共需要p1+p2+······pn种方案。乘法原理做一件事情有n个步骤,第i个步骤有pi种方案,则一共有p1p2······pn种方案。容斥原理这里书上这里写的不好:(截自百度百科,证明过程一般分为计次数和归纳法两种,这里不多作赘述)有重复元素的全排列有k个元素,其中第i个元素有ni个,求全排列的个数。分析:没啥好分析的,这个有高中学历的其实都知道hhhh,答案为(n1+n2+原创 2021-09-11 22:01:28 · 447 阅读 · 0 评论 -
10.1 数论初步
10.1 数论初步这一章开始讲一些关于数论的初步知识。10.1.1 欧几里得算法和唯一分解定理除法表达式给出一个这样的除法表达式,x1/x2/x3···/xk,其中xi是正整数。除法表达式应当按照从左到右的顺序求和,例如1/2/1/2的值为1/4。现在可以在表达式中添加括号用来改变运算顺序。判断是否可以通过添加括号,使表达式的值为整数。分析:首先我们需要知道的是,给表达式中的一段加了括号,相当于对这个括号内的xj前面的/改成了*。我们现在考虑一个情况:假设我们改变了xi到xj之前的符号,然后再原创 2021-09-10 17:52:23 · 264 阅读 · 0 评论 -
9.6 训练参考
依旧鸽子,不过这次不会鸽太久。原创 2021-09-10 00:21:57 · 51 阅读 · 0 评论 -
9.5 竞赛题目选讲
9.5 竞赛题目选讲最近身体不好,还是慢慢看题做题。9-18 跳舞机 (UVA 10618)原创 2021-09-10 00:21:06 · 174 阅读 · 0 评论 -
9.4 更多经典模型
9.4 更多经典模型就是多做点题9.4.1 线性结构上的动态规划最长上升子序列问题(LIS)给定n个整数,按从左到右的顺序选出尽可能多的整数,组成一个严格上升子序列。分析:d[i]表示以第i个整数结尾的最长上升子序列的长度,于是有状态转移方程:d[i]=max{d[j]+(aj<ai)} j<i,i>=2,边界条件就是d[1]=1,求d[n]。这里的算法是O(n2)复杂的算法,然而实际上有更为简单的O(nlogn)的算法书上并没有介绍。然后我去查询了大量的博客,发现其实就是在原创 2021-09-06 23:20:56 · 204 阅读 · 0 评论 -
9.3 多阶段决策问题
9.3 多阶段决策问题这一章先看题。9-4 单向 TSP (UVA 116)给一个m行n列(m<=10,n<=100,这里的数据范围就是提醒大家这是一个宽度可能要远大于长度的矩阵)的整数矩阵,从第一列任何一个位置出发每次向右,右上或右下三个方向选择一个方向走一格,最终到达最后一列。要求经过的整数之和最小。整个矩阵是环形的,即第一行的上一行是最后一行,最后一行的下一行是第一行。输出路径路径每列的行号,多解时输出最小的。分析:状态的设计就比较简单了,d(i,j)表示从格子(i,j)出发到最原创 2021-07-25 08:02:22 · 310 阅读 · 1 评论 -
9.2 DAG上的动态规划
9.2 DAG上的动态规划很多问题都可以转化为DAG上的最长路最短路或路径计数问题。9.2.1 DAG模型嵌套矩形问题有n个矩形,每个矩形可以用两个整数a和b描述,分别表示它的长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)的条件是:a<c且b<d或者a<d且b<c。现在要求在这n个矩形中尽量多的选出若干个矩形排成一行,使得除了最后一个以外,每一个矩形都可以嵌套在下一个矩形内。分析:矩形与矩形之间的嵌套关系是一个典型的二元关系,二元关系可以用图来建模。如果矩形X可以嵌套原创 2021-07-23 10:22:49 · 285 阅读 · 1 评论 -
9.1 数字三角形
9.1 数字三角形这章我们开始介绍一些有关动态规划的知识和问题。动态规划严格意义上说并不是一种特定的算法,而是一种处理问题的思想和手段。9.1.1 问题描述与状态定义数字三角形问题:有一个由非负整数组成的三角形,第一行只有一个数,除了最下行之外的每个数的左下方和右下方各有一个数。从第一行的数开始,每次可以往左下或者右下走一格,直到走到最下行,把沿途经过的所有数全部加起来,如何走才能使得这个和最大。分析:这个问题可以用回溯法解决,但是如果用回溯法求出所有可能的路线的话,一个n层数字三角形的完整路原创 2021-07-21 18:47:09 · 131 阅读 · 0 评论 -
8.7 训练参考
8.7 训练参考原创 2021-07-21 16:17:20 · 48 阅读 · 0 评论 -
8.6 竞赛题目选讲
8.6 竞赛题目选讲量力而行8-10 抄书 (UVA 714)把一个包含m个正整数的划分成k个(1<=k<=m<=500)非空的连续子序列,使得每个正整数恰好属于一个序列。设第i个序列的各数之和为S(i),你的任务是让max{S(i)}最小,输出依次个数字最小的情况。分析:我们现在将这m个整数分割成的区间的区间和的最大值设为x,根据这个x所能够最多分割出的区间个数我们记作P(x),于是这个问题转化为求解的P(x)=k的最小解。然后我们知道P(x)这个函数的值是随着x的增大而不严原创 2021-07-21 15:44:00 · 484 阅读 · 4 评论 -
8.5 算法设计与优化策略
8.5 算法设计与优化策略我们将会在这一章中介绍一些经典问题的处理方法和解决策略。8-1 煎饼 (UVA 120)有一叠煎饼正在锅里,煎饼共有n张,每张都有一个数字,代表它的大小。厨房每次可以选择一个数k,把从锅底开始数第k张上面的煎饼全部翻转,即原来在上面的煎饼现在到了下面。现在需要你设计一种方法使得所有的煎饼按照从小到大排序(即上面的煎饼最小)。输入时,各个煎饼按照从上到下的顺序给出。分析:仔细观察的话我们可以发现这道题是需要我们设计出一种,而不是设计出最短的一种。这里的基本操作类似于“翻转原创 2021-07-16 00:06:51 · 306 阅读 · 1 评论 -
8.4 贪心法 (Greedy Algorithm)
8.4 贪心法 (Greedy Algorithms)贪心法,又称贪婪算法是指,在对问题求解时总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,算法得到的是在某种意义上的局部最优解。贪心算法不是对所有问题都能得到整体最优解,但如果选用策略正确,那么贪心算法往往是易于描述且易于实现的,关键是贪心策略的选择。最优装载问题给出n个物体,第i个物体的重量为wi。选择尽量多的物体,使得总重量不超过C。分析:这个问题非常简单,直观考虑只需将所有物体按重量从小到大排序,依次将最小的物体放入到容原创 2021-06-09 11:03:12 · 648 阅读 · 2 评论 -
8.3 递归与分治
8.3 递归与分治这一章节主要介绍递归除了排序与检索以外,更为广泛的应用(实际上是介绍了递归与分治的使用情况与使用意义)。棋盘覆盖问题有一个2k*2k的方格棋盘,恰好有一个方格为黑色的,其他都为白色。你的任务是用包含3个方格的L型牌覆盖所有白色方格。黑色方格不能被覆盖,且任意一个白色方格不能同时被两个或更多牌覆盖。以下是L型牌的四种旋转方式:分析:本题的棋盘是2k*2k的,如果使用分治法很容易想到将棋盘切割成4块。此时的四个2k-1*2k-1的方块中必有一个含有一个黑色方块,这个方块可以视作k-原创 2021-06-08 12:42:39 · 128 阅读 · 0 评论 -
8.2 再谈排序与检索
8.2 再谈排序与检索这一章的所有问题我都做成详细的问题分析的专题放在另外一个专栏了,大家可以直接看我之前写过的那几篇文章。十大排序算法的简单介绍和代码实现二分查找从归并排序到求解逆序对个数...原创 2021-06-07 17:51:46 · 84 阅读 · 0 评论 -
8.1 算法分析初步
8.1 算法分析初步从这一章开始,我们就正式进入了理论上真正的算法设计理论,学习的算法也逐渐从一些低效的暴力方法,转变为一些经典的高效算法。8.1.1 渐进时间复杂度最大连续和问题:给出一个长度为n的序列A1,A2,A3······An,求最大连续和。换句话说,要求找到1<=i<=j<=n,使得Ai+A(i+1)+A(i+2)······A尽量大。枚举的做法(最为粗糙的做法):#include<iostream>using namespace std;int m原创 2021-06-04 16:51:38 · 150 阅读 · 1 评论 -
7.8 训练参考
7.8 训练参考原创 2021-06-04 14:51:14 · 69 阅读 · 0 评论 -
7.7 竞赛题目选讲
7.7 竞赛题目选讲题目可能有些难,请阅读完前面的篇章后,选择是否进行阅读。7-11 宝箱 (UVA 12325)你有一个体积为N的箱子和两种数量无限的宝物。宝物1的体积为S1,价值为V1;宝物1的体积为S2,价值为V2。你的任务就是计算出最多能装多大价值的宝物。其中每种宝物都必须拿非负整数个。分析:这个问题看起来比较简单,直接枚举宝物1或宝物2的个数,然后尽可能地多拿宝物2或宝物1。但这个时候可能出现一个问题,当S1和S2的值太过于小了,这种做法的复杂度会比较高,代码如下:#include&l原创 2021-05-28 23:48:04 · 140 阅读 · 1 评论 -
7.6 迭代加深搜索 (IDA*算法实战)
7.6 迭代加深搜索大家还是直接通过问题去体会比较好。埃及分数问题对于一个分数a/b,将起转化为多个分子为1的分数之和,表示方式有很多种,其中加数少的比加数多的好,加数相同的情况下,则最小的分数越大越好。例如19/45=1/5+1/6+1/18是最佳方案。分析:这道题如果用回溯法去做,解答树的深度和每一层的宽度都是无法确定的(因为每一层都是无限大的),所以显然不能用我们前面学的两种方法去做。...原创 2021-05-27 00:25:10 · 456 阅读 · 1 评论 -
7.5 路径寻找问题
7.5 路径寻找问题路径寻找问题可以归结为隐式图的遍历,它的任务是找到一条从初始状态到终止状态的最优路径。总体来说和回溯法相似,但是限定的条件上有一些区别(一个是dfs,一个是bfs)。八数码问题编号为1-8的8个正方形滑块被放入3*3的九宫格中(有一个格子留空),每次可以将与空格相邻的滑块(有公共边的方块)移到空格中,而它原来的位置就成为了新的空格。给定初始局面的和目标局面(用0表示空格),你的任务是计算出最少的移动布数。如果无法到达目标局面,则输出-1。样例输入:2 6 4 1 3 7 0原创 2021-05-24 19:08:00 · 189 阅读 · 0 评论 -
7.4 回溯法
7.4 回溯法这一章节相较于前面两章难度更加高一些,实用性也更加广泛。如果可以的话,请务必认真看,大家一起认真学习(我知道你们不会看)。7.4.1 八皇后问题在棋盘上放置八个皇后。使得它们互不攻击,此时每个皇后的攻击范围为同行同列和同对角线(下面图中绿色的部分就是一个皇后棋子的攻击范围),要求找出所有解。分析:如果这道题我们用纯枚举的方法寻找64个格子中长度为8的子集,显然复杂度还是很高的(书上这里第一个提出的方案找子集,这个方案想想就可以了嗷hhhhh)。事实上,我们如果对每一行进行枚举,第原创 2021-05-21 20:39:46 · 314 阅读 · 1 评论 -
7.3 子集生成
7.3 子集生成这一章主要介绍子集生成算法:给定一个集合,枚举出所有可能的子集。首先提前在这里先声明一下,我们会依次学习三种子集生成的方法,但是书上这三种方法的代码都只是得到子集各个元素对应的下标组成的集合,而不是直接得到子集,所以如果需要得到子集还需要对书上的代码进行一系列的调整。7.3.1 增量构造法这个方法理解起来是真的非常困难,我参考了很多博客,才大概明白了个大概,代码如下:...原创 2021-05-20 19:01:10 · 423 阅读 · 2 评论 -
7.2 枚举排列
7.2 枚举排列直接看问题吧,从问题入手感觉会比较简单。7.2.1 生成1-n的排列这个问题就是输出1-n的长度为n的阶乘的一个全排列。那什么叫做全排列呢?我打个比方n=3时,全排列就是(1,2,3),(1,3,2),(2,1,3),(2,3,1),(3,1,2),(3,2,1)。你们可以理解为用1-n组成的所有的不同的排列。我们稍微模拟一下n的情况:先输出以1开头的排列,接下来输出以2开头的排列······输出以n开头的排列。我们单独拿出一个以i开头的排列的情况:第一数为i,后面的n-1位数实原创 2021-05-18 13:29:04 · 209 阅读 · 1 评论 -
7.1 简单枚举
7.1 简单枚举从这一章开始,就正式从工具到学习一些简单的算法基础了。7-1 除法 (UVA 725)输入正整数n,按从小到大输出所有形如abcde/fghij=n的表达式,其中a-j恰好为0-9的一个排列(可以有前导0),n的值小于等于79。分析:非常简单的问题,把fghij按照01234-100000/n枚举一遍就可以了。代码实现如下:#include<iostream>#include<cstring>using namespace std;int a[10]原创 2021-05-17 10:55:29 · 151 阅读 · 0 评论 -
6.6 训练参考
6.6 训练参考等什么时候想得起来再写吧。原创 2021-05-17 10:21:00 · 227 阅读 · 1 评论 -
6.5 竞赛题目选讲
6.5 竞赛题目选讲老生常谈,大家量力而行。6-17 看图写树 (UVA 10562)你的任务就是将多叉树转化为括号表达法,就像下面这样:分析:就是拟态了一个树的样子,其中下面有“|”的字符,就代表为一个根结点。然后输出的话空结点后面跟着一个(),大概就是这样的情况。这个问题不用想,肯定是要用dfs做的,那我们从哪个角度开始呢?肯定是每层往下面找字符,如果这个字符下面啥都没有就直接输出一对括号,如果这个字符下面有"|“就代表有子树,子书下面一长串的”-"我们把这个横线的长度给找到,就可以对下面原创 2021-05-05 16:56:42 · 206 阅读 · 0 评论 -
6.4 图
6.4 图这章的具体内容我们一边做题一边学习。6.4.1 用DFS求连通块6-12 油田(UVA 572)给定一个m*n的字符矩阵,统计由字符"@"组成了多少个连通块。分析:首先我们需要知道什么是连通块。连通块就是指在这个部分中,对于这个部分的任意一个字符,都能找到另外的字符与之相邻(横竖,或者对角线方向)。那我们怎么处理这个问题呢,这里显然用DFS比较好:从每一个"@“出发,递归遍历它周围的”@"格子。每次访问一个格子就给他做上标记,下次遍历时就可以判断它是否被遍历过,或者存在于别的连通块:原创 2021-05-02 06:09:41 · 175 阅读 · 1 评论 -
6.3 树和二叉树
6.3 树和二叉树首先还是了解一下,什么叫树:树是一种数据结构,它是由n个节点和n-1条边组成的一个具有层次关系的集合,每个节点有0个或多个子节点(有一条边连接着的下层节点),0个或一个父节点(有一条边连接着的上层节点),没有父节点的节点称为根节点,除了根节点外,每个子节点可以分为多个不相交的子树。上图中,A节点就是我们所说的根节点,B,C为A的子节点,其中所有的#节点我们都可以称它为这个树的叶节点(没有子节点),又称终端节点。一个节点所含有的子节点的个数我们称其为这个节点的度,A的度为2。一个树原创 2021-04-28 00:44:43 · 269 阅读 · 0 评论 -
6.2 链表
6.2 链表首先还是一个问题,什么叫做链表呢?我们已经学过了数组,和很多的容器,不过可以知道的是,无论选用什么样的容器,里面存储的元素都是按照下标顺序,连续地存储在开辟的空间里。链表,在这里又可称为线性表的链式存储,是一种非顺序的存储结构。每个数据元素在存储的同时,要配备一个指针,用于指向它的直接后继元素,即每一个数据元素都指向下一个数据元素(最后一个指向NULL(空))每个元素本身由两部分组成:1.本身的信息,称为数据域2.指向后继的指针(下标),称为指针域这两部分信息组成数据元素的存储原创 2021-04-26 00:59:08 · 244 阅读 · 0 评论 -
6.1 再谈栈和队列
6.1 再谈栈和队列从这章开始,我们就真正开始对算法的基础篇进行学习啦。在这章,我们会更加深入地了解数据结构,然后学习一些高级内容(的基础)。6-1 并行程序模拟 (UVA 201)原创 2021-04-23 20:12:21 · 173 阅读 · 0 评论 -
5.5 习题
先鸽一会儿啦原创 2021-04-23 13:44:12 · 532 阅读 · 1 评论 -
5.4 竞赛题目举例
5.4 竞赛题目举例老生常谈,由于这本书是服务于竞赛的算法书,所以有些题可能比较难。大家根据自己的需要阅读本章内容。5-8 Unix is 命令 (UVA 400)输入正整数n及n个文件名,排列后按照列优先的方式左对齐输出。假设最长文件名有M字符,则最右列有M字符,其他列都是M+2字符。分析:我一点都没删原封不动打的书上的题面。相信很多人看完都和我一样感觉一头雾水。然后我用我还没过四级的英语去翻译了原题。事实上这里的M+2表示一个文件名占格。然后需要一行需要填满60个格(注意是列优先)。那么这道题原创 2021-04-20 14:31:51 · 126 阅读 · 0 评论 -
5.3 应用:大整数类
5.3 应用:大整数类在学习C语言时,大家会发现很多整数溢出的情况。如果运算结果非常大,就需要用到高精度算法。我们在前面的章节中,用循环的方法模拟过高精度除以低精度的除法运算。那么有没有什么方法,可以像使用int一样方便地使用大整数呢?这里结合前面所学的知识给出一种解决方法。5.3.1 大整数类 Biginteger...原创 2021-04-18 19:33:25 · 460 阅读 · 0 评论 -
5.2 STL初步
5.2 STL初步这一章节我们主要介绍C++的标准模板库。5.2.1 排序与检索关于sort的内容,我在4.2 函数调用与参数传递已经介绍的非常详细了。事实上由于sort是一个模板函数,sort是可以对任意对象(不一定是内置类型)进行排序的。5.2.2 不定长数组 vectorvector是一个封装了动态大小(不固定)数组的顺序容器,它能够存放任意类型的对象。不仅如此,它还将一些常用的操作封装在了vector类型的内部。首先我们看一下怎么声明一个vector://vector<变量原创 2021-04-17 22:19:51 · 231 阅读 · 2 评论