数据结构与算法
文章平均质量分 82
如题,数据结构与算法
harry1213812138
有任何问题可以评论,我会第一时间回复。
在下虽然菜,但是菜的认真。
展开
-
最小路径覆盖与最小链覆盖 Dilworth定理:最小链覆盖等于最长反链(详细证明与经典例题)
一、最小路径覆盖定义最小路径覆盖就是指在有向无环图中,用最少的、不相交的简单路径覆盖图中的所有点。解法①将原图中的每个点拆点,(将点u拆成u与u+n);②将原图中的每条边 <u,v> 在新图中建立对应的边 <u,v+n>;③将点(1 ~ n)作为二分图的左部,将点(n+1 ~ 2*n)作为二分图的右部,进行二分图的最大匹配;④所求的最少路径数等于总点数n 减去 最大匹配数。二、最小链覆盖定义最小链覆盖和最小路径覆盖的区别是,最小链覆盖允许路径相交。最小路径覆盖原创 2021-12-29 19:53:54 · 2557 阅读 · 0 评论 -
一篇树状数组 入门到进阶 实现原理+代码模板详解
一、树状数组的是什么我们首先要了解树状数组是什么,树状数组是一种数据结构。他主要功能是能够高效的实现区间求和以及单点修改操作。我们可以知道,最高效的区间求和是计算前缀和数组从而O(1)O(1)O(1)的实现,但是求完前缀和数组后在进行单点修改的时间复杂度是O(n)O(n)O(n)的(一次单点修改需要修改整个前缀和数组),因此执行m次区间求和以及单点修改的时间复杂度是O(mn)O(mn)O(mn)的。而如果用一个数组存所有数的话区间求和的复杂度是O(n)O(n)O(n)的,而单点修改的复杂度是O(1)O原创 2021-11-10 20:52:06 · 864 阅读 · 0 评论 -
Trie数 字典树 算法思想及代码实现
Trie树Trie树又称字典树,是一种简单的树形数据结构,他的主要作用是高效地存储和查找字符串,其实现原理是利用字符串的公共前缀来减少查询时间,最大限度的减少无谓字符的比较,效率高。三个基本性质根节点不包含字符,除根节点外每一个节点都只包含一个字符;从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串;每个节点的所有子节点包含的字符都不相同。存储规则从根节点开始,存一个字符串,先看根节点连接的子结点有没有第一个字母,有的话接着从他往下找第二个字母,以此类推;若没有某一字母,就原创 2021-08-06 11:52:03 · 230 阅读 · 0 评论 -
单调栈 模型整理与应用 & 经典例题
单调栈单调栈是指一个栈里所有的元素是单调的,单调递增(或递减)的,通过维护这个单调的栈我们可以实现许多的目的。单调栈模型的应用单调栈模型最直接的用处是来求数组每个数的往左第一个比他小的数,或往右第一个比他小的数,这类问题。我们如何来求每个数的左边第一个比它小的数呢?最简单的做法就是从i往左循环,直到找到比他小的数为止。但这样找完n个数,时间复杂度是O(n2)O(n^2)O(n2),有时会超时,那么我们可以用单调栈来求就可以在O(n)O(n)O(n)的复杂度内求出。证明: 我们可以发现第i个数左边可原创 2021-05-09 20:20:23 · 203 阅读 · 0 评论 -
掌握01分数规划 思想+应用模型总结
理解什么是01分数规划首先先分开看一下三个关键词:01、分数、规划这类题一般是给一堆a[i]和一堆b[i],这两个是有联系的,比如第i个物品的收益是a[i],花费是b[i],问选择哪k个物品使得∑选出来的a[i]∑选出来的b[i]\frac{\sum_{选出来的a[i]}}{\sum_{选出来的b[i]}}∑选出来的b[i]∑选出来的a[i]最大,也就是求选出来的平均性价比最高。1、那么01指的什么呢?我们可以这么理解,对于这n个数,每个数我们有两种抉择,选他或者不选他,选用1表示,不选用0表原创 2021-02-01 19:59:44 · 520 阅读 · 1 评论 -
区间和并问题 思路加模板整理(校门外的树)
区间和并区间和并就是将n个区间进行合并,有重叠部分的区间合并成一个新的区间,无重叠部分的区间保持独立,如下图:上面的是原区间1、2、3、4,然后将所有的区间合并,就得到了下面的两个新区间(将1、2合并了)。这就是区间合并问题。思路那么,知道了区间和并是什么之后,我们如何实现合并呢?这里我们可以先对左端点排个序,然后用一个l,r来维护当前区间,①若下一个区间的l <= 当前维护的区间的右端点r,那么我们就将当前区间的r修改成max(r , 下一个区间的r),这里一定是取两者的最大值,因为可能存原创 2021-01-21 12:16:43 · 622 阅读 · 0 评论 -
常用小技巧之折半枚举(超大背包实例)
折半枚举有时候,问题的规模比较大,外面无法枚举所有元素的组合,但能枚举一半或者一部分的组合。此时,将问题拆分成两半或几部分后分别枚举,再合并他们,这一方法往往非常有效。举个例子例题: 给定各有n个整数的四个数列A,B,C,D。要从每个数列中个取出1个数,使四个数的和为0,求出这样组合的个数。当一个组合中有多个相同的数字时,把他们当不同的数字看待。(poj 2785)思路:从四个数列中选...原创 2020-10-28 23:11:34 · 1057 阅读 · 0 评论 -
二分查找(二分搜索)所有情况及模板 简单总结 以及lower_bound函数
二分搜索二分就是不断缩小解空间的范围,从而求得问题的最优解。二分不光可以用在查找某值的位置,也可以用二分搜索法找问题的答案。下面是用二分的各种情况。1、从有序数组中查找某值这是最基本的二分搜索法,若在一个有序数组里找一个数,最朴素的算法就是从头到尾一个一个的找,如此的时间复杂度是O(n),当n很大时找一遍复杂度就很高。此时我们可以利用他的有序性这个特点,我们可以直接从中点查找,若中点的数比查找的数小,我们在右半边接着按照这个方法查找,若中点的数比查找的数大,我们接着在左半边查找,若相等则刚好找到,这时原创 2020-10-18 21:44:11 · 860 阅读 · 0 评论 -
常用小技巧之尺取法
尺取法尺取,又名双指针,一种高效的枚举区间的方法,一般用于求有一定限制的区间个数或最优区间。如求一组数据中不大于某个上限的最优连续子序列。例:subsequence(poj 3061)给定长度为n的整数数列,及一个整数s,求出总和不小于s的连续子序列的长度的最小值,若解不存在,输出0。思路:用尺取法快速求解,从头开始列举子序列,当子序列的和小于s时,右端点继续向右移,当s大于等于15时,记录子序列长度,然后使左端点向右移,直到子序列的和小于s再重复上述操作。枚举每个符合条件的子序列求得最小值。输原创 2020-10-18 11:29:03 · 336 阅读 · 0 评论 -
博弈论总结 四大博弈模型 SG函数
一、博弈论1、博弈论是什么博弈论是二人在平等的对局中各自利用对方的策略变换自己的对抗策略,达到取胜的目的。2、平等博弈在我们平时做题碰见的博弈都是平等博弈,平等博弈满足下面这几个要求:1.两人游戏,每人轮流做出决策,且每人的决策都是对自己有利的。(让自己赢)2.有一个终止状态,到终止状态后游戏结束,不会有平局状态。(获胜的条件)3.游戏可以在有限步数内结束。(不会无限重复,得不到答案)4.所有规定对两人都是一样的。(平等游戏)二、四大博弈1、巴什博弈:1.定义: 只有一堆物品,共n个,原创 2020-09-03 16:18:18 · 10337 阅读 · 0 评论 -
数论之容斥原理 与经典例题
容斥原理容斥原理是对多个集合的一种计数方法。人们为了不重复、不遗漏地计数,想到了一个特别的计数方法,称为容斥原理。简单来说,某个事物有很多类,我们现在要计算A、B、C三类的和,那么总和=A类元素个数+B类元素个数+C类元素个数-既是A又是B类元素个数-既是B又是C类元素个数-既是A又是C类元素个数+既是A又是B又是C类元素个数。这样计算非常方便且不重不漏,我们用一个集合图直观的就能看出这个原理:普遍推广:要计算几个并集的大小,我们要先将所有单个集合的大小计算出来,然后减去所有两个集合相交的大小,然原创 2020-08-31 10:09:21 · 4799 阅读 · 3 评论 -
关于__int128型大数模板 加法乘法板子
1、大数加法模板#include<iostream>using namespace std;inline void read(__int128 &x){ x = 0; int f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch &l原创 2020-08-15 12:15:43 · 382 阅读 · 0 评论 -
一篇线段树 从入门到进阶 实现原理与代码模板
线段树是什么线段树是啥,简单来说就是既方便我们求一个数组某区间的和,又方便我们修改数组的某个元素的一种数据结构。属于二叉搜索树。对于一个普通数组来说,我们修改某一元素的时间复杂度是O(1),但求某区间和的时间复杂度是O(n)。若使用前缀和,我们求某区间和的复杂度是O(1),但我们修改某一元素的复杂度是O(n)。为了方便我们又修改又求和,我们就使用线段树来均衡这两个操作的复杂度,把他们都平均到O(logn)。具体操作我们通常用一个数组来模拟一棵满二叉树,该二叉树的根结点保存的是数组0-n所有元素的原创 2020-08-03 15:15:18 · 303 阅读 · 0 评论 -
图论最短路径之Bellman-Ford算法 代码模板及其优化
一、对比dijkstra算法1、dijkstra算法的局限性dijkstra算法适用的图不能含有负权值的边,若含负权值,可能会导致求得的答案错误。如下图:以0为源点,首先确定到最近的2号点距离为5,然后确定到1号点的距离为7。但实际到2号点可经过1号点中转,经过负权值的边到2号点的距离为2 。所以当图中出现了负权值的边,就要用Bellman-Ford算法。2、Bellman-Ford算法的局限性Bellman-Ford算法的图中不能有负权值回路(总权值和为负数的回路),如下图:此图中0到1出原创 2020-07-22 16:54:21 · 362 阅读 · 0 评论 -
最小生成树 克鲁斯卡尔(kruskal)与普里姆(prim)算法实现及代码实现
一、最小生成树是什么1、生成树:若一个无向连通图G的子图是包含了G的所有顶点的一棵树,则该子图是G的生成树。生成树是图的极小连通子图。简单来说就是删去所有成环的边,使得G变为无环图。2、最小生成树:对无向连通图的生成树中所有边权值和最小的树。最小生成树有三大算法:克鲁斯卡尔算法(Kruskal)、普里姆算法(Prim)、Boruvka算法二、克鲁斯卡尔算法(Kruskal)1、算法思想:克鲁斯卡尔算法以边为主导。设有n个顶点的联通网络G(V,E),①先将所有点取出,构造一个n个顶点0条边的全不原创 2020-07-14 16:26:21 · 556 阅读 · 0 评论 -
c++前缀和与差分
一、前缀和1、简介前缀和也是一个在比赛中比较实用的方法,他能很快得求出一个区间的和,速度为O(1)。一维的前缀和如sum[ i ]是指数组前i位的所有和,如求区间x到y的和只需sum[ y ] - sum[ x ]。二维的前缀和如sum[ i ][ j ]是指(i,j)点的左上角的矩阵和,及0 – i行且0 – j列的和。他可以快速的求出矩阵中任何一个子矩阵的和,如求长为l且右下角顶点为(i,j)的正方形只需sum[ i ][ j ] - sum[ i ][ j-l ] - sum[ i-l ][原创 2020-06-04 17:01:11 · 2167 阅读 · 1 评论 -
一篇并查集 代码模板及经典例题
一、定义并查集就是对集合进行合并及查询,包括两部分,并(union)和查(find)。 “并”是将有关联的元素合并为一个集合,“查”是查找这个元素属于哪个集合。二、代码模板#include<iostream>using namespace std;const int N = 110;int int main(){ return 0;}...原创 2020-06-03 15:22:39 · 531 阅读 · 0 评论 -
一篇搜索及剪枝
一、搜索是什么搜索算法就是查找解空间,他是暴力思想的具体实现,就是把每一种情况都罗列出来,然后逐一检查,找到正确答案。二、搜索的基本算法搜索的基本算法有两种:深度优先搜索(DFS, Depth-First Search)和广度优先搜索(BFS, Breadth-First Search)。搜索的主要步骤是:(1)找到所有可能的数据,并于合适的数据结构表示和存储,一般用DFS和BFS算法。...原创 2020-05-12 11:39:25 · 481 阅读 · 2 评论 -
C++位运算及其相关应用 快速幂及最短Hamilton路径代码模板
基础知识与:&,同为1时为1,否则为0或:|,有1为1,没1为0非:!,1为0,0为1异或:^,相同为0,不同为1,类似不进位加法反码:按位取反补码:反码加1左移位:整体向左移n位,右边补0,相当于乘了2n右移位:整体向右移n位,左边补符号位,相当于删除个位数,除以了2n位运算的应用1.快速幂模板若计算a的n次幂是一般要循环n次,让n个a相乘,时间复杂度为o(n),若...原创 2020-04-09 16:34:17 · 875 阅读 · 1 评论 -
时间复杂度对应常见算法总结
题目给到的数据范围就含有很多信息,有些人一看就能想到可能用到的算法总结一下常见的输入数据大小及可能使用到的算法数据范围可能用到的算法n <= 30指数级别的算法,DFS+剪枝n <= 100n^3,floyed、动态规划n <= 1000n^2,动态规划n <= 10000n*sqrt(n),块状链表n <= 1...原创 2020-04-08 22:55:56 · 462 阅读 · 0 评论 -
一篇动态规划 全解(dp模型整理&背包九讲)
一、啥是动态规划动态规划和贪心一样是求最优解的一种思想、方法,而不像搜索或排序那样有固定的模板和顺序,在使用动态规划时由于各种问题的性质不同,确定最优解的条件也互不相同,因而解题方法也不同,不存在一种万能的动态规划算法。但是我们可以对常用的动归进行总结分析,进而形成对某一类问题的独特解法,方便我们做题。动态规划一般可分为线性动规(拦截导弹),区域动规(石子合并),树形动规(数字三角),背包动规...原创 2020-04-02 17:40:27 · 834 阅读 · 0 评论 -
kmp算法和kmp的优化
一、kmp是什么KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。简单来...原创 2020-03-10 18:50:58 · 1118 阅读 · 1 评论