![](https://img-blog.csdnimg.cn/20201014180756916.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
算法
文章平均质量分 51
风流学霸段公子
小白学习历程
展开
-
dp的刷表法和填表法
刷表法和填表法 实际上我们实际编写代码的过程中也都有遇到,其实就是一个思想的正反两种思考的过程。填表法值得其实就是dp递推过程中,我们采用填充某个位置的方式来递推,刷表法则指的是,用当前这个状态来推导出所有可能涉及到的状态值。 这两个操作本质上其实是一样的,但是某些情况下不同的选择却会有一些不同的代价开销,以及实现的难度,所以我们要针对具体问题设计合理的实现算法。...原创 2021-04-22 11:46:16 · 455 阅读 · 0 评论 -
枚举算法
指数枚举 所谓指数型枚举,实际上指的是子集枚举问题,通常有两种枚举方式。①递归枚举#include<bits/stdc++.h>using namespace std;int num[16];vector<int> ans;int n;void dfs(int k){ if(k==n+1){ for(int i=0;i<ans.size();i++)cout<<ans[i]<<" ";cout<<e原创 2021-04-21 17:19:23 · 417 阅读 · 0 评论 -
网络流算法
网络流最大流算法网络流是图论里面最难,也只最有有魅力的分支,事实上图论中很多问题都可以转化为求解最大流的问题,比如说求解最小割的问题,使用网络流算法会使得求解最小割的时间复杂度降低很多,并且网络流算法还具有很大的普适性。这里我就不多介绍网络流是什么了,相信关于网络流的具体模型,定义有很多科普文章进行了详细的介绍,这里只是给出两种具体的实现算法,以及思想原理。Edmonds-Krap算法 该算法是一种在网络流残余图上寻找增光路的算法,寻找增广路的过程其实就是DFS或者BFS从源点搜索图都可以,但是关原创 2021-03-24 11:35:58 · 2024 阅读 · 0 评论 -
组合数计算
组合数计算 模同余条件下的组合数在很多算法中经常用到,因为组合数要用到数的除法,而模同余对除法并不适用,所以我们先要将分母转化为模p的乘法逆元,这样我们就可以将除法转化为乘法,从而快速求解出问题的模同余意义下的解。 根据费马小定理,有a^(p-1)=1mod p,所以a在模p下的乘法逆元就是a^(p-2),由于乘法在模运算下,是可以先做模运算,再做乘法的。模板#include<bits/stdc++.h>using namespace std;long long jc[1001原创 2021-03-11 21:11:22 · 158 阅读 · 0 评论 -
DP后效性处理方法
后效性DP 从一开始学习DP我们就知道,阶段是DP的三大要素之一,也即要想使用DP则需要保证阶段之间无后效性,也即DP的状态图中不能存在环,但是有些问题在我们抽象出状态转移方程后,却发现这道类似动态规划问题的DP题目却不满足无后效性这一基本条件——部分状态之间的转化相互影响,相互转移构成了环形,无法确定出一个何时的DP阶段,从而沿着某个方向递推。 实际上我们可以将动态规划的各个状态看做是未知量,状态转移看做若干个方程,而这若干个方程与未知量的个数相同,那么我们就可以用求解方式的方式求解出各个状态的值原创 2021-03-02 22:28:17 · 885 阅读 · 0 评论 -
位压缩的常数级优化
位压缩 位压缩是通过k进制的一位来表示数据中一个状态的一种存储压缩方式,它可以在常数级上优化一个算法,例如我们通常所说的状态压缩动态规划,就是用二进制中的一位来表示所求问题中的一个中间状态,当然这样描述还是比较抽象的。 换个例子,对于一个图来说,如果我们只关心两个边之间的相邻关系,那么我们实际上可以用一个二进制位来表示,用0,表示两点之间没有边,而用1表示两点之间存在一条边,那么我们就可以用一个长的二进制串来表示某一点与其他所有点的相邻关系,而二进制串的长度就是所有顶点的个数。这样就比我们直接使用二原创 2021-02-16 13:08:28 · 449 阅读 · 0 评论 -
线段树
线段树 相比于树状数组只能解决计算前缀和的问题,线段树则更为通用,我们可以用线段树实现树状数组所有的功能,但是线段树实现较为复杂,通常可以直接套用模板,再针对具体问题做一些变化,这里不再赘述; 线段树利用冗余存储的方式来加快搜索速度,这是时间与空间折中的经典思想;线段树的形状是一颗完全二叉树,其深度为log2(n)取上整,算下来所有线段树中的节点数不会超会数据个数的4倍,这样我们就可以在初始化时直接设置为原始数据数目的4倍即可; 下面给出一个模板以及例题:线段树模板 相对而言递归实现更容易原创 2021-01-23 21:07:39 · 79 阅读 · 0 评论 -
tarjan算法详解
强连通分量 首先简单介绍一下强连通分量的概念,简单点说就是一个有向图里面,强连通分量里面任意两个点之间的可以互相抵达,则这些点和边组成的子图是一个强连通分量。tarjan算法 网上搜到的算法讲解都是将该算法描述为一个缩点的过程,但是具体讲解时却总是感觉很乱,其实可以更加简单地描述该算法,我的想法本质上与缩点其实是一致的,但是我更愿意将tarjan算法的过程描述为一个将同一个强连通分量上的点打上相同标记的算法。 我们只要理解了强连通分量在图中到底意味着什么,tarjan算法其实就迎刃而解了,那强原创 2021-01-23 15:08:57 · 344 阅读 · 0 评论 -
摊还分析
聚合分析 简单来说聚合分析就是对于一个具有n个操作的问题,我们计算出其最坏情况下花费的总时间为T(n),因此在最坏情况下,每个操作的平均代价,也即摊还代价为T(n)/n; 值的注意的是,摊还代价是针对于每个操作的,并且不管每个操作是否一样,我们仍然认为其摊还代价是相等的,都为T(n)/n; 简单地举一个例子,我们将一个栈的操作进行扩充,增加一个新的操作,pop(k),它指的是将栈中元素弹出连续k个(如果栈中有这么多元素的话,否则将栈弹空为止。)那么在这种新扩充的栈中,我们如何分析各个操作的摊还代原创 2020-12-28 22:20:54 · 153 阅读 · 0 评论 -
RMQ算法
RMQ介绍 要介绍RMQ算法首先要介绍其解决的问题,RMQ是一个解决多个区间最值查询的算法,RMQ(Range Minimum/Maximum Query),即区间最值查询,如果我们要查询某一个区间内的最值,显然我们可以用暴力搜索的方式在O(n)的时间复杂度内获得结果,但是当我们要查询10000个不同区间内的最值时,我们如果依然采用暴力搜索的方式,那么时间复杂度就会变成O(mn),其中m指的是查询次数,n指的是数据个数。 RMQ算法的目标就是降低多区间最值查询问题的时间复杂度,RMQ算法是通过动态规原创 2020-12-21 20:37:13 · 3733 阅读 · 0 评论 -
四大字符串匹配算法总结
字符串匹配问题 首先简单介绍一下字符串匹配问题,字符串匹配问题里面包含一个文本串和一个模式串。我们的目标是找到文本串中与模式串相同的子字符串,该问题就称之为字符串匹配问题。朴素字符串匹配算法 朴素字符串匹配算法其实就是暴力对比的原理,因为模式字符串所有可能的开头只有文本串中每一个字符的位置,所以我们只需要判断以文本串中每一个字符打头时,模式串是否可以匹配文本串。code//朴素算法bool ncmp(string str,string p){ int n=str.length(); in原创 2020-12-03 22:30:12 · 1393 阅读 · 0 评论 -
图和树数据结构
图的表示方式图的表示方式1.领接矩阵 这是图表示的一种经典方式,当图越接近完全图时,领接矩阵的效率就越高,且使用领接矩阵可以在O(1)的时间复杂度内获得边的权值,缺点就是在稀疏图中由于开辟空间的时间复杂度是O(n^2)的,所以时间开销较大,除此之外,使用领接矩阵存储图数据,则其遍历图的时间复杂度一定是O(n ^2)的,下面就简单的以领接矩阵实现的图数据实现其迪杰斯塔拉算法。code#include<bits/stdc++.h>using namespace std;#defi原创 2020-11-19 22:40:52 · 475 阅读 · 0 评论 -
KM算法总结
二分图最大权匹配问题二分图中如果给每条边一个权值,此时求解二分图的权值和最大的完美匹配的问题就是所谓的二分图的最大权匹配问题,对于不是完全二部图的二分图,我们可以添加权值为0的边,使其变为完全二部图。求解方法理论结果从上面的分析可以看出,相等子图里面的最大完美匹配一定是二部图的最大完美匹配,而问题在于相等子图并不一定存在完美匹配,所以现在的问题是如何给相等子图改标号,使得相等子图中的匹配数增加,当相等子图中的匹配数等于最大匹配数时,算法停止。算法匈牙利算法中每次第一步都是选取一个未饱和原创 2020-10-12 15:53:09 · 595 阅读 · 0 评论 -
网络与网络流
网络的定义一个网络N=(V,A)是指一个连通无环弧且满足下列条件的有向图:①有一个顶点子集X,其每个顶点的入度都为0;②有一个与X不想交的子集Y,其每个顶点的出度都为0;③每条弧都有一个非负的权值,称之为弧的容量。以上定义中X称之为源点集,Y称之为汇点集,其他的顶点称之为中转点,网络的容量函数为C。上图所示的两个网络中,(a)中的x1,x2为源点,y1,y2为汇点,其他的节点则为中转点。如果一个网络中只有一个源点和汇点,则称之为单源单汇网络,当然任何一个网络都可以导出一个单源单汇网络,方法如原创 2020-10-12 16:05:38 · 534 阅读 · 0 评论 -
map以及hash_map
原理简介首先map和hash_map都是关联容器,能够实现数据的一对一映射,但是两者在实现上有很大的区别,map的内部机制是红黑树,红黑树是一种特殊的平衡二叉树,所以map中数据查找效率是logn级别的,但是其空间利用率接近100%,也即map开辟的空间中没有不利用的空间。而hash_map本质上是散列表,所以其映射关系是由一个内部的映射函数实现的,也即其实数学中的函数映射,由于函数映射过程中可能产生不同的输入值对应相同的解,所以hash_map中可能会产生散列冲突现象,所以为了避免这种现象,散列表和散列原创 2020-09-20 17:25:22 · 239 阅读 · 0 评论 -
Dijkstra算法实现
原理简介Dijkstra作为一种求解单元最短路的算法,其本质是贪心的,他保证了当前将要加入到已经求解出最短路的点集合S的点到源点的距离,一定是小于后面加入的所有点的。问题引入概率最大路径分析:该题中所求的概率最大路,具有dijkstra求解的单元最短路的特性,因为概率乘法是单调递减的,意味着Dijkstra算法中求解过程中,先确定最短路的点,一定会比后面的概率大,也即满足贪心的性质,只要我们已经求出某一点的概率最大路径, 那么后面不可能再产生到该点概率更大的路径。算法实现dijstra实现:原创 2020-09-18 21:31:38 · 184 阅读 · 0 评论 -
算法中的零和博弈
零和博弈概念介绍零和博弈就是字面意思所表示的博弈情形,博弈双方在博弈过程中的总价值是不变的,双方某一方价值的增长必然会导致另一方价值的缩减,零和博弈是具有先手优势和后手劣势的。先手优势所谓先手优势其实指的是博弈双方具有优先选择权的一方,具有优先选择的优势,他可以优先控制选择的走向。后手劣势后手劣势指的是博弈双方中,后手一方在选择时会受到先手优势的影响,尽管博弈双方都可以选择最有利于自己的顺序进行,但是后手是在先手制约下的最优选择,所以后手是博弈双方中具有劣势的一方。总之零和博弈作为一种常见原创 2020-09-11 15:18:36 · 2076 阅读 · 0 评论 -
状态压缩动态规划
状态压缩动态规划什么是状态压缩动态规划\qquad状态压缩动态规划又称之为状压DP,这是针对NP难问题的一种特殊的动态规划技巧,状态压缩动态规划顾名思义,就是状态压缩+动态规划,首先讲一下动态规划适用情形。\qquad动态规划适用的调价是有子问题,且子问题有重叠,动态规划问题理论上都可以用递归算法来解决,但是递归算法往往要用到很多递归栈,且对子问题无法进行区分,所以对于子问题重叠问题,递归算法效率不足,因此子问题重叠的问题,通常采用动态规划的算法。\qquad本质上动态规划也是穷举搜索,而非局部搜索原创 2020-07-04 10:58:39 · 256 阅读 · 0 评论 -
最大公因子||最大公约数
辗转相除法证明:假设存在整数a,b其中a大于b。那么有a=kb+r成立,其中r为a除以b所留余数。假设a,b的最大公约数为m,那么a/m为整数,由此可得(kb+r)/m为整数。又因为b/m为整数,则r/m也是整数,即m也是r的因子,又因为m为(kb+r)与b的最大公因子,那么如果r与b的最大公因子大于m,那么一位置存在n>m使得b/n,r/n为整数,那么意味着(kb+r)/n为整...原创 2019-11-04 19:21:06 · 1289 阅读 · 0 评论 -
算法导论——动态规划
动态规划动态规划问题与分治问题类似。都可以通过组合子问题来求解问题的解。什么是分治法?分治法是指将问题划分为互不相交的子问题,然后通过递归或者迭代求解每个子问题,再将子问题的解组合起来得到原问题解的一种策略。由于分治法的子问题是互斥的,所以解决此类问题应该用递归法,而不是动态规划。研究问题动态规划主要研究子问题重叠的情况,由于递归方法在求解子问题重叠的问题时,会将每一个分支产生的问题都...原创 2019-10-19 11:46:26 · 328 阅读 · 0 评论 -
C++中algorithm用法
max()函数max函数用来求两个数之中较大的数,返回值为两者之中较大的数。cout<<max(2,3)<<endl;输出结果:3原创 2019-10-10 19:18:08 · 588 阅读 · 0 评论 -
C++字符串操作函数
关于string.h,cstring和string的区别:string.h 是C版本的头文件,包含比如strcpy、strcat之类的字符串处理函数。cstring 在C++标准化(1998年)过程中,为了兼容以前,标准化组织将所有这些文件都进行了新的定义,加入到了标准库中,加入后的文件名就新增了一个”c”前缀并且去掉了.h的后缀名,所以string.h头文件成了cstring头文件。所以,s...原创 2019-10-10 16:41:10 · 384 阅读 · 0 评论 -
C++STL日积月累
sort()函数用法①Sort函数包含在头文件为#include的c++标准库中,调用标准库里的排序方法可以不必知道其内部是如何实现的,只要出现我们想要的结果即可!②Sort函数有三个参数:(1)第一个是要排序的数组的起始地址。(2)第二个是结束的地址(最后一位要排序的地址)(3)第三个参数是排序的方法,可以是从大到小也可是从小到大,还可以不写第三个参数,此时默认的排序方法是从小到大排序...原创 2019-10-10 16:19:01 · 128 阅读 · 0 评论 -
最小割的求解算法
最小割的求解算法分析欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入欢迎使用Ma...原创 2019-09-23 20:14:02 · 3803 阅读 · 0 评论