算法基础课
Kris Wang24
这个作者很懒,什么都没留下…
展开
-
算法基础课:区间DP
首先区间DP:顾名思义:区间dp就是在区间上进行动态规划,求解一段区间上的最优解。主要是通过合并小区间的 最优解进而得出整个大区间上最优解的dp算法。 既然让我求解在一个区间上的最优解,那么我把这个区间分割成一个个小区间,求解每个小区间的最优解,再合并小区间得到大区间即可。所以在写代码时必须要将区间从小到大枚举,为的是保证后面大的区间所用到的已经是被算过了,然后开始枚举左端点,枚举完左端点以后,再确立右端点,此步实质上是确定区间的一个过程,最后一步再去枚举我中间的分点即可。 代码模板: 在这里插入代码片 i原创 2020-07-04 15:16:17 · 233 阅读 · 0 评论 -
算法基础课:动态规划之背包问题
首先动态规划,应该理解为一个递推的过程,很多时候对于动态规划来说都应该是从前向后递推的一个过程。但是思考的方式还是应该按照递归的思想来去思考,比如说按照集合划分,状态表示,状态表示又可以划分成状态表示的东西是什么?状态表示的条件是什么,属性又是什么?状态计算就是正常的一个递推的过程,思考方式是该属性可以来源于哪些部分,然后然后以递推的方式进行即可。 01背包:每个物体只有选与不选。 完全背包:每个物体可以选择无数次。 多重背包:每个物体只能选择有限次。 分组背包:分成若干组,每次只能从每组之中选择一个(类似原创 2020-07-03 22:20:23 · 209 阅读 · 0 评论 -
算法基础课:集合结构
堆: 首先来讲什么是堆,首先,对于堆来说,分为大根堆,小根堆,其维护是应用数组来维护,对于堆来说有几个常用操作: 增加新元素,删除元素,调整堆序。 堆的常见应用:优先队列。 对于此来说常常应用于维护最大最小值的集合。 哈希表:将大范围的数,映射到一个小范围上。 对于哈希表,在C++里一般用STL实现。 ...原创 2020-07-01 16:48:49 · 158 阅读 · 0 评论 -
算法基础课:线性结构
1:链表,顾名思义,就是一个向链子一样套在一起的结点,对于每个结点,分为地址和数据两个块,在算法竞赛中我们常常使用静态链表(数组模拟链表) 也就是说对于链表我们什么时候使用这个数据结构呢? 通常情况下,我们对于需要频繁插入和删除的数据结构我们才会使用链表,因为此时对于插入和删除的时间复杂度是O(1)对于链表个人感觉感觉用的最多的地方还是在于邻接表和哈希里。 下面讲讲静态链表: ...原创 2020-06-30 22:50:45 · 147 阅读 · 0 评论 -
算法基础课:双指针算法
首先对于双指针算法,必须明确,对于此问题来说,只能是一个优化问题,核心思想是把一个O(n2)的时间复杂度问题给优化到O(N)来解决。 通用模板: 按照朴素算法: for(int i=0;i<n;i++) for(int j=0;j<n;j++) { 具体问题的逻辑 } 按照某种性质进行优化: for(int i-0,j=0;i<n;i++) while(j<i&&check(i,j)(某种属性)) { 每道题目具体逻辑 } 具体题目举例: 给定一个长度为n的整数原创 2020-06-29 12:04:57 · 154 阅读 · 0 评论 -
算法基础课:前缀和与差分
对于前缀和:实质上就是背公式, 对于前缀和分一维和二维首先应该是一维前缀和的公式: s[i]=s[i-1]+a[i]; a[i]+=a[i-1]; 常用的就是这两个公式,对于前缀和实质就是某一段区间的和。作用:求出某一段区间的和。 比如说对于[l,r]这个区间,我们应该做的就是s[r]-s[l-1]即可。 对于二维前缀和我们也叫做矩阵的和: 对于矩阵的和应该如何取? s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j] a[i][j]+=a[i-1][j]+a[i]原创 2020-06-29 09:55:31 · 208 阅读 · 0 评论 -
算法基础课:高精度
j高精度算法:常用的有加减,对于乘除我们只会用小数乘大数。 首先对于高精度加法,应该使用string类来进行表示,然后对于此类问题还需要特别注意的就是对于一个大数来说,我们应该进行倒置,这样对于加减来说更为有利。对于高精度加法模板如下:应该先设置一个t=0;然后分别加上每一个数的对应位即可解决问题。 对于高精度减法注意的点就比较多了: 1:首先对于高精度减法来说,首先最重要的就是确定大小,应该是大数减小数,那么如何大数减小数呢,此时涉及到的细节就比较多: 比较大小: 首先应该是将size进行比较,若size原创 2020-06-28 22:36:51 · 137 阅读 · 0 评论 -
算法基础课:二分
整数二分: 对于一个区间,必须具有左属性,右属性,对于二分本质来说,就是可以找到这个属性的边界值,单调必然可以二分(因为左右两部不同)对于整数二分分两种情况,第一种是满足左属性,另一种是满足右属性。 对于左属性模板: int l,r; l=left,r=right; while(l<r) { int mid=(l+r+1)>>1; if(check(mid))(写题的时候关键是check函数,确定左部属性还是右部属性) l=mid; else r=mid-1; } ...原创 2020-06-28 21:34:35 · 111 阅读 · 0 评论