自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(49)
  • 收藏
  • 关注

原创 算法分析与设计 第四章思维导图

2021-11-24 12:24:53 242

原创 算法设计与分析第三章思维导图

2021-11-01 23:16:27 166

原创 算法设计与分析 第二章

2021-10-09 20:40:00 102

原创 算法设计与分析第一章思维导图

2021-09-21 16:58:07 169

原创 动态规划之背包问题

(随时更新)AcWing 11. 背包问题求方案数/*i, j, k : 前i个物品中,选了若干件,其体积小于等于j,且价值为k的所有方案。属性:数量集合划分:包含i:其数量等于dp{i - 1, j - vi, k - wi}不包含i:其数量等于dp{i - 1, j, k}dp[i][j][k] = dp[i - 1][j - vi][k - wi] + dp[i - 1][j][k];体积太大,会MLE。yxc做法:dp[i][j]集合描述 : 前i个物品中,选择了

2021-05-19 17:00:05 74

原创 动态规划之初始化与遍历

初始化一直是我比较困惑的地方。根据总结,我发现了以下规律:先明白,不合法的集合:根据集合的文字描述,不符合语义的集合。279. 自然数拆分{i, j}: 在前i个数中,选择了若干数,其和为j的所有方案。属性:方案数。那么{0, 1}的文字描述,就是不选数的情况下,和为1的所有方案。该集合肯定是不合法的集合,因此,应该被认为是空集。有些合法的集合,根据题目给定的样例不同,也可以是空集。既然是空集,那么如果是和的最大值,它的属性就应该被赋值为一个不可能在题目中可能出现的和的数。如果是方案数,

2021-05-18 18:30:56 448

原创 动态规划之线性DP

最长上升子序列模型最长上升子序列模型有些题目,要求你求出一个最佳序列。这个序列的元素不一定是数。分级先要知道一个定理:B序列的所有元素肯定都在A序列中出现过。在得到答案的算法推进过程中,我们要暴力枚举出所有的B序列。在暴力枚举所有B序列的过程中,也会枚举出一些中间序列(类似于dfs中的状态节点)。将这些序列按某一特征进行划分。集合:{i, j}:与A[1……i]配对,且以A1[j]结尾的B序列。(A1[j]是排序好的A序列)属性:dp[i][j] : MIN S集合划分:遮掉A[j],

2021-05-09 16:46:18 97

原创 动态规划之数字三角形模型

题目给你一个二维数组(每一行的列数不一定相等)。让你求出一条最佳路径。dp[i][j] : 从(1, 1)走到(i, j)的所有路径集合。属性:MAXSUM集合划分:按照路径的倒数第二个值进行子集划分。先把集合中的所有路径的(i, j)给遮住,然后将这些路径按照路径的最后一个点是否相等划分到不同的集合。在把(i, j)加上,就把所有的路径都给划分好了。求属性:我们要求{i, j}集合里的所有路径的最大值,等价于求所有子集的最大值。对{i, j}划分好的一个子集G,它包含的所有路径,肯定是从(1

2021-05-09 16:43:18 108

原创 动态规划之最长上升子序列模型

有些题目,让求给定序列的最*** 的 ***序列。五一到了,ACM队组织大家去登山观光,队员们发现山上一个有N个景点,并且决定按照顺序来浏览这些景点,即每次所浏览景点的编号都要大于前一个浏览景点的编号。同时队员们还有另一个登山习惯,就是不连续浏览海拔相同的两个景点,并且一旦开始下山,就不再向上走了。队员们希望在满足上面条件的同时,尽可能多的浏览景点,你能帮他们找出最多可能浏览的景点数么?题目让求最长的子序列,该子序列满足单调递增或者先递增后递减或者递减。我们要得到最长的子序列,就需要枚举出所有

2021-05-07 21:09:11 140 1

原创 算法的时间、空间、性能分析

一.想要预估算法的运行时间,可以先计算测试样例的时间;然后将测试样例翻倍,记录时间;然后再翻倍……得到如下模型:样例(N)运行时间(T(N))Nx12Nx24Nx38Nx416N?做图像x轴为lgN,y轴为lg(T(N))。我们一般可以得到一个斜率为b的直线。lg(T(N)) = blgN + c同时取2的幂,就可以得到 T(N) = aN^b (a = 2 ^ c)二.我们想要知道算法内部具体发生了什么,导致了这样的运行时间。我们可以知

2021-04-03 23:27:43 823

原创 并查集

一.数学模型:给定一组对象集合,标号为0 ~ N - 1。我们需要两个操作:连接两个对象检查两个对象是否被连接二.“连接”的性质:对象与它自己是连接的连接满足传递性连接满足对称性因此我们连接两个对象,实际上两个对象所在的连通分量之内的所有对象也都相互连接了。连通分量的性质:连通分量里的对象相互连接连通分量里的对象与连通分量外的对象不连接在算法实现的时候,我们不需要记录具体的连接方案。因此连接两个对象的操作可以看作两个对象连通分量的合并操作。而查找操作只需要查找两个对象是否在

2021-04-03 22:57:16 45

原创 蓝桥杯

dfs单词重排将每个字母看作1 ~ 7的数字求全排列时,要注意有两个相同的字母,即最后求出来的每一个排列,存在另一个唯一的排列与之相等。除以2即可。合法括号序列数字三角形七段码求全排列+判环的题bfs作物杂交状态转移容易出错。没理解“同时可以进行多个杂交过程”的意思,导致错误。逆序对问题:排序树叶节点数暴力换算计算机知识。成绩统计暴力模拟,求及格率/优秀率回文日期数学数字 9暴力取模,求每个数字中某一数字出现的个数。门牌制作同数字9约数个数求某一个数的约数

2021-03-25 21:15:20 137

原创 搜索之广搜变形

有的时候我们会遇到边权不为1的图,求最短路径。我们第一时间考虑到的是dijstra算法。这个算法的思路是什么?我们假设用一个数据结构ds维护遍历到的节点到起始节点a的距离。这个ds中肯定有一个最小值len,len对应的节点b到节点a的最短距离即为len。为什么呢?ds中的其他距离都大于len,那么从这些节点扩展到a的距离也一定大于len,而还未遍历到的节点到起点的距离还要长。因此当b第一次出队时,就可以保证已经求出了它到起点的最短距离。需要注意的是一个节点可能被入队多次,我们最好记录它们是否出队,因为第n次

2021-03-14 19:21:16 131

原创 搜索之广度优先搜索

广度优先搜索按层次遍历决策树。队列中的元素满足“两端性”和“单调性”,因此它能够求出某一状态到起始状态的“最短路径”。如果把分支的看作边权为1的边,也就相当于求出了最短路。BFS一般都会给你一个二维矩阵,然后告诉你或者可以转换为求从某一状态到另一状态的最短距离。立体推箱子把每一个状态看作一个节点,状态的分支看作边权为1的边,题目相当于求边权为1的图的最短路径。矩阵距离多源BFS问题。把矩阵看作边权为1的图,1代表的点是起点,题目相当于求图的任一节点到起点的最短距离。多源Bfs的做法是把所有起点入

2021-03-14 18:57:03 125

原创 蓝桥杯模拟题

子串分值#include <iostream>#include <algorithm>using namespace std;const int N = 30;const int M = 10005;int main(){ string s; cin >> s; int n = s.size(); int last[N], left[M], right[M]; fill(last, last + N, -1); for (int

2021-03-12 11:39:14 73

原创 搜索之深度优先搜索

学了算法竞赛进阶指南的DFS章节后,我对“状态”和“阶段”有了更深刻的理解。阶段:问题是被一步步解决的。面临的每一个步骤都是一个“阶段”。状态:状态表示每个阶段开始所处的自然状况或者客观条件。小猫爬山我们可以依次把每只小猫放到缆车上。第一个思路是枚举缆车数量,再放小猫。每只小猫可以放到这些缆车中的任何一个。依次搜索每只小猫,会超时。仔细观察,对于第一只小猫,它放到任何一个缆车上都是等价的。因此会有很多冗余情况。第二个思路是直接放小猫。对于每个状态,我们只需要知道是 枚举的是第几只小猫,有几架缆车

2021-03-07 21:27:41 167

原创 搜索之树与图的遍历

树与图的深度优先遍历:树与图的深度优先遍历能确定树的DFS序、深度和重心树与图的广度优先遍历图的广度优先遍历能确定有向无环图的拓扑排序:可达性统计题目提到了有向无环图,可以尝试拓扑排序的思路。拓扑序列topA有个很好的性质:对于每一条边(x, y),x在topA中一定排在y之前。定义size(x)为点x能到达的点的集合。我们发现,若A点存在且只存在边(A, B), (A, C),那么size(A) = size(B) | size© + 1(|代表求并集)。逆序遍历拓扑序列topA,对于每一个

2021-03-04 11:33:57 132 1

原创 基本运算之递归

维基百科上的解释:递归(英语:Recursion),又译为递回,在数学与计算机科学中,是指在函数的定义中使用函数自身的方法。我们通常使用函数来解决原问题,同时这个函数也能够解决于原问题类型相同的子问题。我们求解同类型的子问题,如果子问题的解可以扩展到原问题的解,那么就能获得原问题的答案。如何求解子问题? 函数是求解特定类型的问题的步骤与方法,因此直接代入函数即可,这就是“函数的定义中使用函数自身。因为求解原问题与求解子问题的方法相同,因此又将子问题分解成了规模更小的问题……这样一直重复问题步骤,直到“问

2021-03-02 13:35:27 116

原创 基础运算之倍增

天才ACM倍增 + 归并思路。难度较大。

2021-02-28 15:42:45 78

原创 基础数据结构之二叉堆

二叉堆一般用于涉及插入、删除、查询最值得题目。往往配合其它题型使用。超市贪心题目。需要用到二叉堆的查询最值、插入和删除功能。序列多路归并问题。注意到是求和问题,题目让求m个序列“合并”得到的n个值,如果我们得到了前m - 1个序列“合并”n个值,那么只需要把这n个值看成一个新的序列,转换成两个序列“合并”成n个值的问题。很明显用递归或递推都可以。我们只需要解决如何“合并”两个序列即可。两个序列如何合并呢?A : a1 a2 a3 a4 …… an(A已经排好序)B : b1 b2 b3 b4

2021-02-24 18:13:33 110

原创 基础数据结构之trie树

Trie树是一种实现字符串快速检索的多叉树结构。把一堆字符串压缩到树结构中构成Trie树,实现快速检索。Trie树的题一般应用于“前缀检索”、“最大异或值”这类题。先把全部数据储存到Trie树中,再遍历每个数据,进行检索。前缀检索前缀统计电话列表很简单的题。可以先把数据全部保存到Trie树中再检索,也可以边插入边判断。最大异或值最大异或对涉及到位运算的题,可以把数字看成31位二进制数,再把每一位看成一个字符,转换为Trie树问题。将每个数按二进制位从高到低保存到Trie树中,然后再遍历

2021-02-24 17:12:31 90

原创 进制转换模板题 AcWing 124. 数的进制转换

https://www.acwing.com/problem/content/description/126/#include <iostream>#include <vector>#include <algorithm>using namespace std;int main() { int n; cin >> n; while (n --) { int num1, num2; str.

2021-02-20 11:23:34 91

原创 二分答案转换为判定的题型

二分答案转换为判定问题:这个方法是怎么想到的呢?我做的题不多,试着依照现有的做题量,来总结了下这些题目的思考过程。(实时更新)AcWing 102. 最佳牛围栏最优解问题。题目描述:给定正整数序列A,每个长度大于等于L的字段都有一个平均值,求最大平均值。如果暴力枚举的化,就是枚举每个方案。每个方案都有一个对应的平均值。现在方案作为定义域,将平均值作为值域。以“每个符合要求的字段”作为定义域,“字段对应的平均数”作为值域,按值域从小到大排序,可以画出一个图。题目要求的最大平均值就是值域最大值S。

2021-02-20 11:23:18 214

原创 ACWing 96. 奇怪的汉诺塔

#include <iostream>#include <cstring>using namespace std;int main() { int d[20], f[20]; d[1] = 1; for (int i = 2; i <= 12; i ++) { d[i] = d[i - 1] * 2 + 1; } memset(f, 0x3f, sizeof f); f[1]

2021-02-20 11:22:54 68

原创 基础数据结构之字符串

字符串的两种经典算法:KMP算法和最小表示法。KMP算法《算法竞赛进阶指南》上的推导过程写的很详细,推荐看一下。推导过程的难点在于要理解如何遍历某一位置i的“候选值”集合。理解之后其它问题就都迎刃而解了。周期KMP算法推导过程中“自我匹配”的next数组的应用。next[i]表示字符串A中“以i结尾的非前缀子串”和“A的前缀”能够匹配的最长长度。我们发现,如果字符串存在循环节,那么肯定存在某一非前缀后缀等于某一前缀。该匹配长度肯定是“候选值”集合中的一个值,那么该值是否就是next[i]呢?

2021-02-16 21:42:21 148

原创 基础数据结构之链表和邻接表

邻值查找题目让求min1≤j<i|Ai−Aj|。我们将所有数放到数轴上,题目等价于让求和Ai靠的最近的元素A[j],并且满足j < i。我们发现如果排好序,那么对原序列的最后一个数来讲,是可以无视“j < i”这个条件。逆序遍历原序列的每一个数Ai,找到它在排好序的序列中的位置Bj,比较与它相近的两个数Bj - 1和Bj + 1。之后再删去Bj。删除操作如果用数组储存,时间复杂度为O(n^2);用链表是O(1)。...

2021-02-16 18:51:40 118

原创 基础数据结构之队列题型

队列是一种先进先出的数据结构。有一些题目我们需要先推导它们的性质,然后根据其性质使用队列。这种题目的难度往往较大。蚯蚓双端队列单调队列问题单调队列是一种经典题型。和单调栈一样,保存一堆单调递增的数据。不同的是,单调队列需要从最前面的元素开始操作,单调栈需要从最后面的元素进行操作。最大子序和...

2021-02-16 18:25:08 168

原创 字符串的最小表示法

求一个字符串中,它长度为len的子串的最小表示。AcWing 137. 雪花雪花雪花

2021-02-10 18:44:53 94

原创 基础数据结构之哈希题型

字符串HashAcWing 138. 兔子与兔子(模板题)套用这个模板,我们可以求得字符串中,任意一个子串的哈希。步骤是先求字符串的前缀(后缀)hash(特别要注意求前缀的方法,一个规模小的前缀是如何推到规模大的前缀的: h[i] = h[i - 1] * base + s[i] - ‘a’ - 1)。有了前缀hash值之后,可以求得任意子串s[L – R]的hash值:h[L – R] = h[R] - h[L - 1] * p[R - L + 1] (p数组存的是base的“下标”次方)。再遇到

2021-02-10 18:30:57 140

原创 栈的题型

两个栈的配合建立两个栈,可以实现O(1)查询最小值的操作。https://www.acwing.com/problem/content/90/“对顶栈”的应用https://www.acwing.com/problem/content/130/进出栈序列问题题目:给定1~N这N个整数和一个无限大的栈,每个数都要进栈并出栈一次。如果进栈的顺序为1,2……N,那么可能的出栈顺序有多少种?方法一:dfs方法二:递推方法三:动态规划方法四:卡斯兰数表达式计算:题型:后缀表达式

2021-02-06 12:50:19 116

原创 AcWing 124. 数的进制转换 (进制转换题型的万能模板)

https://www.acwing.com/problem/content/126/#include <iostream>#include <vector>#include <algorithm>using namespace std;int main() { int n; cin >> n; while (n --) { int num1, num2; string s1, s2;.

2021-02-04 12:07:42 112

原创 分治好题 AcWing 119. 袭击

https://www.acwing.com/problem/content/121/最近点对问题。分治思想:将这些点按x值从小到大排序,排序后的下标范围是[l, r]。现在用一个递归函数,求出[l, mid]这些点中的最短距离s1,[mid + 1, r]的最短距离s2。现在有3种情况:最佳答案在[l, mid]中最佳答案在[mid + 1, r]中最佳答案中的两个点,一个在[l, mid]中,一个在[mid + 1, r]中前两种都好说,答案就是min(s1, s2)。麻烦的是.

2021-01-29 19:37:06 331 1

原创 排序的几种题型

离散化的应用(用排序建立映射)AcWing 103. 电影(应用)https://www.acwing.com/problem/content/105/给定N个数,1,2,100000,1000000,3……,N不大,但是数很大。此时可以先对这些数排序,放到一个数组里,这样就建立了这些数与0,1,2……N的映射。之后用1,2……N来代替这些数,可以建立更方便的映射。如果这些数中有重复,需要去重,当然可以顺便把数量记录下来。因为已经排好序,所以可以使用二分查找来搜索100000映射的整数是0,1,2

2021-01-28 16:53:03 298

原创 贪心题型

AcWing 110. 防晒https://www.acwing.com/problem/content/112/区间匹配问题:给定一些区间和一些点,每个区间能与一些点配对。求最大的配对数量。做法:按区间的 起点 从小到大排序,逆序遍历 每个区间i(也可以直接从大到小排序),在与区间i相匹配的每个点中,选择最大的点。STL快速做法:用map储存点,upper_bound查找第一个大于区间终点的key值迭代器it,然后it- -即为能与区间匹配的最大点题目出现的特征:第i头奶牛需要**m

2021-01-28 12:57:00 126

原创 基本运算之二分

二分的两种用法:求边界将最优解问题转换为判定问题三分:用来求函数极值https://www.acwing.com/problem/content/104/用到了二分的第二种用法,前缀和,和平均值的数学知识题目可以抽象为对给定数目个数为N的序列,在所有长度大于等于F的子序列中,求出最大平均值将最优解问题转换为二分的判定问题。 为什么可以转换?原因在于在所有可能的平均值(平均值按升序排列)中,任取x0,如果存在子序列的平均值大于x0,则答案肯定在x0的左侧;如果都小于x0,那么答案

2021-01-18 21:28:55 137

原创 基本运算之差分 ACWing 100. 增减序列 AcWing 101. 最高的牛

差分的前缀和就是原序列。换句话说,每个差分序列都有唯一对应的一个原序列。因此可以把差分序列看作原序列的另一个表现形式。差分常用于处理区间问题。对于[l, r]区间,让其每个数加上C,相当于对应的差分序列B[l] + C, B[r + 1] - C。https://www.acwing.com/problem/content/102/题目要求让所有数都相等,等价于要求B[2] ……B[n]等于0。对区间的操作相当于对差分序列的“单点操作”。题目又要求最小的操作次数,因此我们可以尽量优先操作B[2…

2021-01-17 21:04:52 173

原创 递推 AcWing 95. 费解的开关

思路:枚举第一行的所有情况枚举完第一行后,固定住第一行,此时第二行按哪个按钮是确定的。假设第一行某盏灯是0,那么需要按第二行对应的灯泡来改变第一行。同理,操作第三行和第四行遍历第五行看看是否都为1。如果都为1,则达到目标。#include <iostream>#include <cstring>using namespace std;char g[10][10];int dirX[5] = {0, 1, -1, 0, 0};int dirY[5] = {0,

2021-01-13 17:08:13 117

原创 位运算的应用1:使用int型数字表示状态 ACWing 92. 递归实现指数型枚举

从 1~n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。#include <iostream>#include <vector>using namespace std;void DFS(int n, int state, int num) { for (int i = 0; i < n; i ++) { if (state >> i & 1) { cout << i + 1

2021-01-13 09:16:47 69

原创 ACWing 91. 最短Hamilton路径

动态规划讨价还价。让求从0到n-1的最短哈密顿路径。0到n-1范围太大,如果0到n-2多好,0到n-3多好……如何描述这些子题目:i、j描述的是0到j的哈密顿路径。i表示每个点都被拜访过。所以状态就是i、j注意到如果0到n-1有一条最短路径,那么0到n-2的路径一定也是最短的。所以dp[i][j] = min(dp[i][j], dp[i ^ 1 << j][k] + weight[k][j])#include <iostream>#include <cstri

2021-01-12 15:08:31 100

原创 动态规划 leetcode 132

dp[i]:将[0……i]分割成回文子串的最小分割次数对任意状态i,为了达成题目目的,我们第一步应该怎么做?第一步应该分割哪里?我们开始枚举分割位置,假设我枚举到j位置,假设规模小的问题dp[j]已知,那么只需要判断s[j +1……i]是不是回文串即可。如果是,那么dp[i] = dp[j] + 1。如果不是,则跳过。为什么跳过?因为我们是枚举[0, i)所有的j值。对于s[j +1……i],如果不是回文子串,那么需要再次分割至少1次。在哪个位置分割呢?我们后面枚举j值的时候一定能枚举到。所以不用担心,因

2021-01-11 17:42:54 44

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除