基础算法模板总结
文章平均质量分 59
各种算法模板总结
Alkali!
本科:NUAACCST16191
硕士:SEUCSE220
展开
-
用两个栈实现一个队列 思想以及Java实现代码
定义两个栈,s1和s2。原创 2022-10-15 23:26:31 · 433 阅读 · 0 评论 -
中心扩展法求解 leetcode 647.回文子串 & leeccode 5.最长回文子串
想象一下单个字符的哪个中心点扩展可以得到这个子串?所以中心点不能只有单个字符构成,还要包括两个字符,比如上面这个子串。看起来像是和字符串长度相等,但你会发现,如果是这样,上面的例子永远也搜不到。这个是确定了一个中心点后的寻找的路径,然后我们只要寻找到所有的中心点,问题就解决了。先求出最大的回文子串长度,再在求回文子串的过程中,求出最长长度的回文子串。这是一个比较巧妙的方法,实质的思路和动态规划的思路类似。在前面求一个字符串的所有回文子串的基础上,改良一下。,所以是回文串,继续扩散,同理。...原创 2022-08-18 13:51:27 · 94 阅读 · 0 评论 -
AcWing 1303. 斐波那契前 n 项和 矩阵快速幂 题解
题目思路我们可以设Fn=[fn,fn+1]F_{n}=[f_{n},f_{n+1}]Fn=[fn,fn+1]则Fn+1=[fn+1,fn+2]F_{n+1}=[f_{n+1},f_{n+2}]Fn+1=[fn+1,fn+2]那我们要求一个2×22\times22×2的矩阵AAA,使得Fn×A=Fn+1F_{n}\times A=F_{n+1}Fn×A=Fn+1则可以使用矩阵快速幂我们又发现,这道题它要求的是前nnn项和,那其实可以再FFF向量后面加一列代码#i原创 2022-04-01 09:12:02 · 646 阅读 · 0 评论 -
线段树 思想以及基本实现
数据结构特点为什么叫线段树?因为它是把原序列以及其子序列(一个个线段)组织成一棵树的形式。树的根节点为原序列,子节点依次对半分序列,直到叶节点,叶节点是单个数,也没办法再往下分了。而对于每个结点而言,它存储了三个属性:结点所表示区间(线段)的左端点LLL结点所表示区间(线段)的右端点RRR结点所表示区间(线段)的和sumsumsum样例:1-7的序列组织成线段树实际存储的数据结构整体上类似于堆的存储结构:下标从1开始的一维数组父节点:x>>1左儿子:x<&原创 2022-03-24 14:55:00 · 161 阅读 · 0 评论 -
树状数组 思路以及性能分析
特点代码短、常数很小应用及时间复杂度区间查询:求前缀和单点修改:给某个位置上的数加上一个数(同时能以非常小的代价维护前缀和)时间复杂度:O(logn)O(logn)O(logn)与一般前缀和算法的对比算法修改某个点查询前缀和平均时间复杂度(假定两种操作各占50%50\%50%)一般前缀和O(n)O(n)O(n)O(1)O(1)O(1)O(n)O(n)O(n)树状数组O(logn)O(logn)O(logn)O(logn)O(logn)O(logn原创 2022-03-22 20:35:14 · 436 阅读 · 0 评论 -
AcWing 1207. 大臣的旅费 题解 树的最大路径(直径)
题目思路连接各大城市的整个高速路是一颗树说明整个高速路不存在环,是一棵树输入格式这边的强调也应征了连接各大城市的高速路其实是一棵树如果不在某个城市停下来修整,在连续行进过程中,他所花的路费与他已走过的距离的关系设距离为sss,花费f(s)=10s+s(s+1)2f(s)=10s+\frac{s(s+1)}{2}f(s)=10s+2s(s+1)问题让我们求的是什么?J大臣想知道:他从某一个城市出发,中间不休息,到达另一个城市,所有可能花费的路费中最多是多少呢?也即这棵树中任原创 2022-03-16 21:44:38 · 571 阅读 · 0 评论 -
AcWing 1233. 全球变暖 题解 floodfill bfs
题目思路首先通过floodfillfloodfillfloodfill算法,找出整个图中的连通块数,每个连通块对应一个岛屿全球变暖,所有连通块的边界点都被淹没,当且仅当一个连通块中的边界点数和总点数相同时,该岛屿会被全部淹没所以可以在floodfillfloodfillfloodfill计算连通块的过程中,计算出每个连通块的总点数totaltotaltotal和边界点数boundboundbound,判断其是否相等,相等的话就说明其会被全部淹没,记录会被全部淹没的岛屿个数,即为所求因为f原创 2022-03-16 20:07:41 · 565 阅读 · 0 评论 -
【背包问题】思路及模板代码
0-1背包问题题目背景思路原创 2022-02-22 10:51:17 · 481 阅读 · 0 评论 -
AcWing 1209. 带分数 题解 嵌套dfs
题目思路先枚举a,再在每次枚举到a的一种情况时,枚举一下c,最后判断b是否成立参考题解:https://www.acwing.com/solution/content/38879/代码#include<iostream>#include<cstring>using namespace std;typedef long long LL;const int N=20;bool st[N],backup[N];int ans=0,n;bool check(i原创 2022-03-07 23:04:48 · 202 阅读 · 0 评论 -
代码实现三种数字枚举方式 有助于理解递归+dfs
指数型枚举从 1∼n 这 n 个整数中随机选取任意多个,输出所有可能的选择方案。每个数都可选可不选。//每一个数都可选可不选#include<iostream>using namespace std;const int N=20;int n;bool st[N];void dfs(int u){ if(u>n) { for(int i=1;i<=n;i++){ if(st[i])原创 2022-03-07 21:46:10 · 259 阅读 · 0 评论 -
AcWing 125. 耍杂技的牛 题解 贪心
题目思路代码#include<iostream>#include<algorithm>using namespace std;const int N=5e4+10;typedef pair<int,int> PII; //因为要以s和w的和来排序,所以可以用pair对PII cow[N];int n,w,s;int main(){ scanf("%d",&n); for(int i=0;i<n;i++)原创 2022-02-28 16:29:40 · 226 阅读 · 0 评论 -
AcWing 104. 货仓选址 题解 贪心 绝对值不等式
题目思路先把A1到An按值从小到大排序假定货舱选在任意一个位置x处,则f(x)f(x)f(x)如上图一前一后依次给他们分组若要∣a−x∣+∣b−x∣|a-x|+|b-x|∣a−x∣+∣b−x∣取最小值,只有a≤x≤ba≤x≤ba≤x≤b时,最小值为b−ab-ab−a(在a,b两侧取得话,均比这个值要大)所以找一个x的位置,满足每一组都能取最小值,即x取在整个序列的中间(即取整个序列的中位数)对于序列为奇数个的情况,中位数存在,就是中间那个数对于序列为偶数个的情况,中位数有两个,随便取原创 2022-02-28 09:23:41 · 454 阅读 · 0 评论 -
AcWing 913. 排队打水 题解 贪心
题目思路代码#include<iostream>#include<algorithm>using namespace std;const int N=1e5+10;typedef long long LL;int n,t[N];int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&t[i]); sort(t+1,t+1+n); LL原创 2022-02-28 08:54:49 · 292 阅读 · 0 评论 -
AcWing 148. 合并果子 题解 霍夫曼树
题目思路代码#include<iostream>#include<queue>using namespace std;int main(){ int n,a; scanf("%d",&n); priority_queue<int,vector<int>,greater<int>> heap; //优先队列,小顶堆 for(int i=0;i<n;i++) {原创 2022-02-27 19:40:21 · 160 阅读 · 0 评论 -
AcWing 907. 区间覆盖 题解 贪心
题目思路代码#include<iostream>#include<algorithm>using namespace std;const int N=1e5+10;struct range{ int l,r; bool operator<(const range &w)const { return l<w.l; }}range[N];int n,a,b;int main(){原创 2022-02-27 18:58:58 · 203 阅读 · 0 评论 -
AcWing 906. 区间分组 题解 贪心
题目思路时间复杂度主要在排序代码#include<iostream>#include<algorithm>#include<queue>using namespace std;const int N=1e5+10;struct range{ int l,r; bool operator<(const range &w)const //重载<,按左端点排序 { return l原创 2022-02-27 16:53:50 · 326 阅读 · 0 评论 -
AcWing 905. 区间选点 (AcWing 908. 最大不相交区间数量) 题解 贪心
题目思路碰到区间之类的问题,贪心的思路都是先按某种性质排序,再利用某种性质再遍历判断先将每个区间按右端点从小到大排序再从前往后依次枚举每个区间1.如果当前区间中已经包含点,则直接pass2.否则,选择当前区间的右端点时间复杂度:O(nlogn)O(nlogn)O(nlogn) (主要在排序上)代码#include<iostream>#include<algorithm>using namespace std;const int N=1e5+10;原创 2022-02-27 15:03:12 · 497 阅读 · 0 评论 -
AcWing 901. 滑雪 题解 记忆化搜索
题目思路:记忆化搜索记忆化搜索的本质还是DP,但是实现方式和传统DP不一样,采用的是一种递归的实现方式。(图片有误,转换中向上的公式和向下的公式颠倒了)解释状态计算为什么可以这么算?以向右滑举例:如果在(i,j)(i,j)(i,j)处可以向右滑,那么f[i,j]=f[i,j+1]+1f[i,j]=f[i,j+1]+1f[i,j]=f[i,j+1]+1如果可以向右滑,那么(i,j)(i,j)(i,j)处的高度一定大于(i,j+1)(i,j+1)(i,j+1)处以及它能滑到的路径上所有区域原创 2022-02-26 19:08:22 · 297 阅读 · 0 评论 -
AcWing 285. 没有上司的舞会 题解 树形DP DFS
题目思路原理是树形DP,实现方式是DFS代码#include<iostream>#include<cstring>using namespace std;const int N=6010;int h[N],ne[N],e[N],idx;int happy[N];bool has_father[N]; //记录每个结点是否有父结点,为了找到根节点int f[N][2]; //属性dp的全局表格int n;void add(int a,int b)原创 2022-02-26 16:38:27 · 204 阅读 · 0 评论 -
AcWing 91. 最短Hamilton路径 题解 状态压缩DP
题目汉密尔顿是由Hamiltonian音译而来,又有人称为哈密顿。哈密顿图(汉密尔顿图)(英语:Hamiltonian path,或Traceable path)是一个无向图,由天文学家哈密顿提出,由指定的起点前往指定的终点,途中经过所有其他节点且只经过一次。思路代码#include<iostream>#include<cstring>using namespace std;const int N=21,M=1<<N;int f[M][N],原创 2022-02-26 15:40:41 · 311 阅读 · 0 评论 -
AcWing 291. 蒙德里安的梦想 题解 状态压缩DP
题目思路先放横着的,再放竖着的。总方案数,等于 只放横着的小方块的合法方案数。如何判断当前方案是否合法?所有剩余位置,能否填充满竖着的小方块(可以按列来看,每一列内部所有连续的空着的小方块,需要是偶数个)状态表示f[i,j]f[i,j]f[i,j]表示已经将前i−1i-1i−1列摆好,且从第i−1i-1i−1列,伸出到第iii列的状态是jjj的所有方案数。状态转移时间复杂度代码/*下文对 if((j&k )==0 && st[ j| k]原创 2022-02-26 10:41:35 · 168 阅读 · 0 评论 -
AcWing 338. 计数问题 题解 数位统计DP
题目思路分情况讨论[a,b],0−9[a,b],0-9[a,b],0−9我们可以实现一个count函数:count(n,x)count(n,x)count(n,x),1~n中x出现的次数最后的答案就是count(b,x)−count(a−1,x)count(b,x)-count(a-1,x)count(b,x)−count(a−1,x)举例:1~n,x=1n=abcdefg分别求出1在每一位上出现的次数求1在第4位上出现的次数:1<=xxx1yyy<=abcdefg原创 2022-02-25 20:12:12 · 417 阅读 · 2 评论 -
AcWing 900. 整数划分 题解 计数类DP
题目思路状态表示f[i,j]f[i,j]f[i,j]集合所有总和是iii,并且恰好表示成jjj个数的和的方案数。属性数量状态计算可以把f[i,j]f[i,j]f[i,j]的所有方案分为两类:方案里的j个数最小值是1f[i,j]=f[i−1,j−1]f[i,j]=f[i-1,j-1]f[i,j]=f[i−1,j−1]那满足这个条件的方案数 等价于 把这个最小的1拿走的方案数方案里的j个数最小值大于1f[i,j]=f[i−j,j]f[i,j]=f[i-j,j]f[i,j]=f[原创 2022-02-25 16:53:11 · 211 阅读 · 0 评论 -
AcWing 282. 石子合并 题解 区间DP
题目思路集合所有将第iii堆石子到第jjj堆石子合并成一堆石子的合并方式属性minminmin状态计算状态转移方程:当i≠ji≠ji=j时:f[i,j]=min{f[i,k]+f[k+1,j]+s[j]−s[i−1]}f[i,j]=\min\{f[i,k]+f[k+1,j]+s[j]-s[i-1]\}f[i,j]=min{f[i,k]+f[k+1,j]+s[j]−s[i−1]}当i=ji=ji=j时:f[i,j]=0f[i,j]=0f[i,j]=0 单堆石子谈不上合并,原创 2022-02-24 15:20:08 · 574 阅读 · 0 评论 -
博弈论 思路及模板代码
公平组合游戏ICG定义若一个游戏满足:由两名玩家交替行动在游戏进程的任意时刻,可以执行的合法行动与轮到哪名玩家无关不能行动的玩家判负则称该游戏为一个公平组合游戏。Nim博弈属于公平组合游戏,但是城建的棋类游戏,比如围棋,就不是公平组合游戏。因为围棋交战双方分别只能落黑子和白子。胜负判定也比较复杂,不满足条件2和条件3。例题举例1:AcWing 891.Nim游戏给定n堆石子,两位玩家轮流操作,每次操作可以从任意一堆石子中拿走任意数量的石子(可以拿完,但不能不拿),最后无法进行操作的人原创 2022-02-17 19:12:35 · 1812 阅读 · 0 评论 -
容斥原理 原理及模板代码
原理不看每项的系数,容斥原理公式的每一项合起来,其实是把所有情况都选择了一遍(只选一个,只选两个,只选三个,只选四个…),除了一个也不选的情况。然后每项的系数,随着选中数目的增加,在1和-1之间交替。应用举例题目背景思路这是一道典型的容斥原理应用题。求1~n中有多少数是p的倍数,即n/p(下取整)求1~n中有多少数既是p1的倍数,也是p2的倍数,即求1到n中有多少数是它们最小公倍数的倍数:n/(p1*p2)(因为p1和p2是质数,没有公因子,所以它们的最小公倍数就是它们的乘积)原创 2022-02-16 17:48:42 · 771 阅读 · 1 评论 -
卡特兰数 概念及应用
概念Cn2n−Cn−12n=Cn2nn+1C_{n}^{2n}-C_{n-1}^{2n}=\frac{C_{n}^{2n}}{n+1}Cn2n−Cn−12n=n+1Cn2n应用一题目背景解题思路将 01 序列置于坐标系中,起点定于原点。若 0 表示向右走,1 表示向上走,那么任何前缀中 0 的个数不少于 1 的个数就转化为,路径上的任意一点,横坐标大于等于纵坐标。题目所求即为这样的合法路径数量。下图中,表示从 (0,0) 走到 (n,n) 的路径,在绿线及以下表示合法,若触碰红线即不合原创 2022-02-15 20:42:39 · 163 阅读 · 0 评论 -
求组合数 原理及模板代码
类型一:事先把C数组预处理出来(递推)题目背景思路根据组合数递推公式,先把要用到范围内的组合数事先预处理打表出来Cab=Ca−1b+Ca−1b−1C_{a}^{b}=C_{a-1}^{b}+C_{a-1}^{b-1}Cab=Ca−1b+Ca−1b−1证明:在a个球中取b个球,有多少种取法?有CabC_{a}^{b}Cab种可以认为有一个球c十分特别,那取b个球就有两种取法:取到c还是不取到c取到c: Ca−1b−1C_{a-1}^{b-1}Ca−1b−1(在另外a-1个球原创 2022-02-15 20:19:51 · 673 阅读 · 0 评论 -
高斯消元法 思路及模板代码
思路及步骤最后的到一个(近似)阶梯形矩阵再把它化简成近似单位矩阵,即可得到解模板代码在这里插入代码片原创 2022-02-14 17:05:44 · 1048 阅读 · 0 评论 -
中国剩余定理(孙子定理) 原理及模板代码
背景简介孙子定理是中国古代求解一次同余式组的方法。是数论中一个重要定理。又称中国余数定理。一元线性同余方程组问题最早可见于中国南北朝时期(公元5世纪)的数学著作《孙子算经》卷下第二十六题,叫做“物不知数”问题,原文如下:有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?即,一个整数除以三余二,除以五余三,除以七余二,求这个整数。《孙子算经》中首次提到了同余方程组问题,以及以上具体问题的解法,因此在中文数学文献中也会将中国剩余定理称为孙子定理。原理模板代码#inc原创 2022-02-13 11:17:58 · 826 阅读 · 0 评论 -
扩展欧几里得算法 思想及模板代码
题目背景裴蜀定理:裴蜀定理(或贝祖定理)得名于法国数学家艾蒂安·裴蜀,说明了对任何整数aaa、bbb和它们的最大公约数ddd,关于未知数xxx和yyy的线性不定方程(称为裴蜀等式):若aaa,bbb是整数,且gcd(a,b)=dgcd(a,b)=dgcd(a,b)=d,那么对于任意的整数xxx,yyy,ax+byax+byax+by都一定是ddd的倍数,特别地,一定存在整数xxx,yyy,使ax+by=dax+by=dax+by=d成立。裴蜀定理证明:现要求用扩展欧几里得方法,对每两个正整数a,b原创 2022-02-12 17:30:45 · 1028 阅读 · 2 评论 -
快速幂 思路及模板代码
问题背景快速求解ab % p的问题时间复杂度:O(logb)O(logb)O(logb)若对于n组数据,那么时间复杂度为O(n×logb)O(n\times logb)O(n×logb)思路模板代码//题目背景:AcWing 875LL qmi(int a,int b,int p) //求a的b次方对p取模的值{ LL res=1; //res初值为1,是最后的答案 while(b) //b在循环中不断右移,b不等于0 { if(b&原创 2022-02-12 12:01:45 · 574 阅读 · 0 评论 -
欧拉函数 原理及应用
欧拉函数定义欧拉函数证明1∼N 中与 N 互质的数的个数被称为欧拉函数,求欧拉函数的值,其实就是在计算1∼N 中与 N 互质的数的个数。首先把N分解质因数,然后再逐步把与N不互质的数去掉,即质因子的倍数,在去的过程中可能出现多去了的情况,这时要补上。计算欧拉函数代码分析直接用定义求欧拉函数//题目背景:AcWing 873#include<iostream>using namespace std;int main(){ int n,a; scanf(原创 2022-02-12 11:11:18 · 1308 阅读 · 0 评论 -
约数 相关问题(试除法求约数、求约数个数、求约数和、欧几里得法求最大公约数)
约数定义约数,又称因数。整数aaa除以整数b(b≠0)b(b≠0)b(b=0) 除得的商正好是整数而没有余数,我们就说aaa能被bbb整除,或bbb能整除aaa。aaa称为bbb的倍数,bbb称为aaa的约数。在大学之前,"约数"一词所指的一般只限于正约数。约数和倍数都是二元关系的概念,不能孤立地说某个整数是约数或倍数。一个整数的约数是有限的。同时,它可以在特定情况下成为公约数。试除法求一个数的所有约数时间复杂度:O(n)O(\sqrt{n})O(n)#include<iostream原创 2022-02-11 16:27:46 · 778 阅读 · 0 评论 -
质数相关问题(判定、分解、筛选)
质数定义质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数(规定1既不是质数也不是合数)。质数的判定——试除法模板代码bool is_prime(int x) //判断x是不是质数{ if(x<2) //如果x小于2,那x肯定不是质数 return false; for(int i=2;i<=x/i;i++) //从2遍历到x/i的所有数 if(x%i==0)原创 2022-02-09 15:46:51 · 1661 阅读 · 3 评论 -
匈牙利算法求解二分图的最大匹配
题目背景算法思想如果你想找的妹子已经有了男朋友,你就去问问她男朋友,你有没有备胎,把这个让给我好吧多么真实而实用的算法TIP: 因为你要去问的都是男孩子,所以存边的时候,都是由男孩子指向女孩子时间复杂度:O(n×m)O(n\times m)O(n×m)但是实际情况下,会远小于这个复杂度模板代码#include<iostream>#include<cstring>using namespace std;const int N=1010,M=100010;原创 2022-02-08 11:16:16 · 649 阅读 · 0 评论 -
染色法判定二分图 算法思想及模板代码
问题描述判断一个图是否为二分图二分图:二分图又称作二部图,是图论中的一种 特殊模型 。. 设G= (V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集 (A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集 (i in A,j in B),则称图G为一个二分图。算法思想由定理可知:我们这里采用染色的方式来判断一个图是否为二分图将所有点分成两个集合,使得所有边只出现在集合之间,就是二分图二分图:一定不含有奇数环,可能包含长度为偶数的环, 不一定原创 2022-02-08 09:57:52 · 345 阅读 · 0 评论 -
最小生成树 算法思想及模板代码
问题描述及解法分类一般不用堆优化版的Prim算法,直接用朴素版的Prim算法。对于稀疏图而言,点多,边少,适合用克鲁斯卡尔算法对于稠密图而言,点少,边多,适合用普利姆算法Prim算法算法思想prim 算法干的事情是:给定一个无向图,在图中选择若干条边把图的所有节点连起来。要求边长之和最小。在图论中,叫做求最小生成树。prim 算法采用的是一种贪心的策略。每次将离连通部分的最近的点和点对应的边加入的连通部分,连通部分逐渐扩大,最后将整个图连通起来,并且边长之和最小。我们将图中各个节点用数字原创 2022-02-07 22:22:06 · 719 阅读 · 0 评论 -
最短路问题 思路及模板代码
问题分类与简介n表示点的数量,m表示边的数量算法题中对最短路问题的考察,重点不在于证明算法的正确性,对算法的原理要求并不高,考察的重点在于,如何根据问题背景,建图,将问题抽象为图论中的最短路问题。朴素dijkstra算法应用场合单源最短路所有边权为正数点数比较少,但是边数比较多的稠密图(当m和n2是一个级别时)算法复杂度O(n2)算法思路因为是稀疏图,所以用邻接矩阵来存储图模板代码//题目背景:AcWing 849int g[N][N]; //邻接矩阵int dis原创 2022-02-07 11:33:00 · 647 阅读 · 0 评论 -
树和图的存储与遍历 思想+模板代码
树和图的存储树的本质是连通的无环图图分为有向图无向图无向图是特殊的有向图所以对树和图的存储,最本质的其实就是去存储有向图有两种结构:邻接矩阵缺陷:1.不能存储重边,只能保留两个点之间的一条边2.空间复杂度为O(n2),比较费存储空间,只适用于稠密图邻接表为每个结点开一条表示其所有邻接点的单链表,链表上每个结点就是其邻接点链表内部的邻接点次序无关紧要,为方便起见,插入邻接点统一在表头插入一般用数组模拟,数组模拟的效率>vectorint h[N],e[N],ne[原创 2022-01-30 17:31:46 · 1053 阅读 · 0 评论