NOIP算法概论-程序员宅基地

技术标签: 算法  基础算法概论  高中竞赛  noip  高中NOIP C++  

之前高一参加比赛前,曾写过总结,主要是提醒自己NOIP所需要的基本算法,以及至少所需要掌握的数据结构。

当然,NOIP,最重要的算法,只有一个,THAT IS “搜索大法”

练好了搜索,今后的所有竞赛,题目哪怕拿不了满分,至少30+,说不定60+。自己脑补一下优化,100分就到手啦。。。

第一篇正儿八经的博客(别管前面那篇):请各位OIER们,一定一定,要练习搜索,必须练习搜索,而且搜索MUST成为你最拿手的算法!!!

今天的主题是算法概论,就是大概提及一下各个算法啦,貌似也有些没提及(那就拜托无所不能的度娘啦,不过有些具体的算法,我会在后面具体提到的)。

AND 这是高一写的稿子,有啥表述不清的,甚至错误的,请各位体谅!

一.基础思想

1.1二分答案

   noip考试中经常会出现二分答案题目,二分答案,其实是一种思想而并非一种准确的算法,多与模拟,贪心,图论算法相结合。比如说noip2015day2第一题跳石头,noip疫情控制,noip借教室等好多题都可以考虑这种思想。尤其是题目中出现了最大值最小或是最小值最大一般都是二分答案。所以,考试时必须时刻提醒自己要注意往二分答案这方面想。那么二分答案为什么难呢,其一是压根就没往这方面想,其二就是很难check()。check()才是二分答案的关键,容易的直接贪心模拟,比如去年的跳石头,但疫情控制则是二分答案+倍增+贪心的组合题。

那么对于如何书写好check,那就只能靠个人能力了。不过,我们思考时一定要抓住当前分出的答案mid,想好如何会使所求解不满足于当前答案,当发现所求解>mid时该怎么办。从这几个方向去思考会比较容易的得出答案。

1.2贪心

   贪心可以是最不靠谱的解法,也可以是最靠谱的解法。一切都要看你如何去贪,再你码完搜索不会写时,贪心可以帮你。不过除非你百分之百确定贪心的正确性,最好不要只交个贪心上去。贪心其实与最难的dp有很多相像之处,但最大的区别就是有无后效性。这类题目在noip中出现也很多,容易题有不少,但是很多难题多多少少有些思想在其中。这一部分只能考试前多刷题,提高思考能力,考试时自己好好想。    

1.3分治

   分治也是思想,有太多的数据结构,算法要用到分治了。二分答案虽然被我拿出去那是因为太重要了,但二分答案说到根本还是分治思想。分治可以对于多个对象分,答案可以分,操作可以分,最常见的还是算法分治。也就是用分治算法解题,比如:解方程,求平面各种点对等等题目。

1.4倍增

   倍增也是几乎年年多考的题目,倍增,就是字面上的意思,成倍的增长,成倍的跳跃。可以在树上倍增比如说求解lca,在图上同样也可以倍增。倍增多适用于询问很多,但很少修改的题目。如果修改多的话,多用线段树,树链剖分维护。倍增需要注意的地方就是先前的预处理上,以lca举例,预处理时我们求解x的祖先时就要注意(1<<i)<dep[x]。求lca时,先求出两者的差,从小到大枚举,保证(1<<i)&t,使得两者处于同一高度,然后从大到小枚举,保证每次两者的祖先不相等的情况下跳跃。考试时打完倍增一定要注意认真检查,倍增中有很多细节,万一你从大到小搞反了,马上就是0分。

1.5动归

   动态规划,一直以来OIER考试中最难的题目类型。动归也是我最差的算法,难就难在难设计状态,难在如何根据状态找出关系,推出方程。当然,对于这类题目也不是全无办法,最好的就是搜索,把搜索的状态设计好后就可以打出记忆化搜索,记忆化虽然逊色于动归,但如果状态设计的好切题也不是问题。动归在考前就一定要从简单模板开始打起,先把各钟模板打好,然后在认真思考想方法将模板复杂度减小(其实很有用,很多考试都会考模板,但关键是你能否看出来,看出来后能否保证不会超时)。动归考的是个人的分析题目能力,这只能靠多写题,多思考,多请教别人来提高。

二.图论

2.1 SPFA

SPFA是Bellman-ford算法的优化,其实就是在此基础上加了个队列优化,使得只有每次被更新的才会进入队列。SPFA算法时间复杂度更Dijkstra+堆差不多,但是相比而言,Dijkstra+堆更加稳定。

2.2 Dijkstra+heap   

    迪杰斯特拉加堆与SPFA一样,都是求单源最短路径,也就是一个起点,一个终点。但要比SPFA稳定的多,并不容易被随意卡掉。NOIP中此算法用的很多。代码详见资料。

2.3树链剖分

    树链剖分针对的是树上的操作,通常题目要么对于树上是有修改操作的,要么则是求树中一条路径上的最大值/最小值/其它与边息息相关的。

2.4 LCA

    树上最近公共祖先,这个考点一直以来考得很多。之前考得货车运输就是一道裸的lca题目,还有好几题都需要运用到lca。求lca大概有三种方法。第一种就是倍增,倍增在求lca中用的极多,也很好写,只要不把for的顺序搞反一般就没事了。树链剖分也可以求解lca,这一般是比较难的题才用的,因为树链剖分支持树上权值修改,虽然不好打,但可以快速修改,快速询问。第三种是树状数组求lca,用的比较少,就不说了。

2.5拓扑排序

    拓扑排序是在有向无环图上进行的操作,作用是求出一个先后顺序。当然,拓扑排序也可以起到判断有无环,若有环,那么一定进行。在noip考试中拓扑排序考得并不多,但是当我们看到要求操作的先后顺序时,拓扑排序就大有作用了。算法很简单,每次选入度为0的点加入拓扑序列,将与此点直接连通的所有点的入度全部减一,由此重复下去直到不满足为止。

2.6生成树

    生成树在noip考试中用的很多,最小生成树,最大生成树更是经常用到。虽然考试不见得会考裸题目,但是很多题目都得先用生成树将图转变为树后,再在树上进行操作。求最小大生成树都是用克鲁斯卡尔,即贪心思想+并查集。这类题目很灵活,但关键是分析具体题目并求解。

2.7 tarjan

    tarjan算法才是图论中的重难点。tarjan算法用处很多,诸如:求强连通分量,强连通图,割点,割边(桥),还可以将求出的强连通分量缩点。

算法主要部分就是dfs,其中起关键作用的就是low[]数组和dfn[]数组。两个数组都是记录dfs访问到的时间的,low数组是指最早访问到的时间,dfn数组则是指最近一次访问到的时间。

求强连通分量,每一次递归时low[u]=dfn[u]=index++;index是访问时间,而在通过u节点扩展时,若发现(u,v)相连,且v节点未被访问过,那么low[u]=min(low[u],low[v]);(意思就是说因为v是u的子节点,若发现之前曾访问过v节点,则此时更新low[u]的值)。若发现v已经访问过了,那么low[u]=min(low[u],dfn[v]),意思就是说让子树根的low编号最小。当发现low[u]==dfn[u]时就可以判定此点为强连通子图的根,那么此时就可以直接让控制stack的sp指针-,将元素出栈输出了。若要求连通图,想必也是这里动手脚

求割点:若low[v]>=dfn[u],则u为割点,节点v的子孙和节点u形成一个块。因为这说明v的子孙不能够通过其他边到达u的祖先,这样去掉u之后,图必然分裂为两个子图。这样我们处理点u时,首先递归u的子节点v,然后从v回溯至u后,如果发现上述不等式成立,则找到了一个割点u,并且u和v的子树构成一个块。

求桥:若low[v]>dfn[u],则(u,v)为割边。但是实际处理时我们并不这样判断,因为有的图上可能有重边,这样不好处理。我们记录每条边的标号(一条无向边拆成的两条有向边标号相同),记录每个点的父亲到它的边的标号,如果边(u,v)是v的父亲边,就不能用dfn[u]更新low[v]。这样如果遍历完v的所有子节点后,发现low[v]=dfn[v],说明u的父亲边(u,v)为割边。

2.8缩点

    缩点在noip考试中经常会用到,缩点一般是用并查集将所有连通块求出。通过fa数组即可知这n个点将会被缩成几个点,可以用于优化。除此,由于tarjan算法可以求出强连通分量,所以tarjan也可以进行缩点。

2.9强连通分量

    前面tarjan算法中曾介绍过此算法,在此不做介绍。

2.10 二分图

    二分图匹配也是图论的重要算法,求最大匹配可以用匈牙利算法,求最大完美匹配则是用KM算法,虽然它们的理论复杂度并不低,但实际上却是跑的很快。二分图与网络流密不可分,由于难度问题,在联赛中考的不多。

2.11 网络流

    网络流分为费用流和最大流。两类题目几乎不考,当然,如果没有其他方法,也可以往网络流这方面想。

2.12 并查集

    最基础的图论算法之一,前面写了蛮多用到并查集的算法(生成树,缩点),有很多题目都可以用并查集来维护。思想很简单,每个点最初都是一个独立的连通块,若有边与之相连,那么就将它们fa值赋为一样,即在同一连通块中。

三.字符串处理

3.1 kmp

    KMP算法是最基础的字符串算法,用于字符串快速匹配。算法很简单,核心思想就是失败数组的运用,但利用kmp算法的过程出一些比较鬼的题目。比如说:codevs上的动物园,

3.2哈希

    哈希算法很好写,hash[i]=hash[i-1]*p+s[i],p一般取31,而mod一般为1e9+7。对于字符串的子串的哈希值等于hash[r]-hash[l-1]*(p^(r-l+1))。

四.搜索

4.1 DFS

    DFS作为最基本的暴力算法,每一场考试都会考。要注意设计DFS的状态,还要注意不会走回头路。但是,在迷宫等求解方案的时候还是多用BFS。

4.2 BFS

   BFS一般相对DFS用的少一些,多用于迷宫路径求解。

4.3 记忆化搜索

     记忆化搜索并不是每道题都可以的,有些题可以,也有些题不行。一般如果满足无论何时到达此点,此点和到达此点之后的状态都不变的情况下就可以用记忆化搜索。如果重复到达此点后状态发生了改变那么记忆化搜索就不适用了。记忆化搜索是解决可以dp的问题的好方法之一。当然,设计的状态也一定要设计好。

 

 

五.其它

5.1 快速幂

快速幂就不多说了吧,算法的核心是将x^y用二进制来乘,与矩阵快速幂一样。

Res=x;while(y>0) if(y&1) res=res*x%mod;x=(x*x)%mod,y>>=1;这样就可以使速度达到log级别。

5.2 高精度

    高精度是个很麻烦的东西呀,现打很容易出现错误。但是,有些题目,满分only高精度。这一方面,自己一定要多练习,搞清原理后,有事没事打一打。嘿嘿?

5.3 逆序对

    求解逆序对有两种方法,要么归并排序,要么用树状数组求解。考试中考的还是挺多的,一般都是序列问题。后面会具体介绍。

5.4 离散化

     是否离散化,跟题目类型,题目数据有很大关系,请各位出门左转,度娘搜一波,满满的方法。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/LORD_ZEUS/article/details/82955286

智能推荐

获取大于等于一个整数的最小2次幂算法(HashMap#tableSizeFor)_整数 最小的2的几次方-程序员宅基地

文章浏览阅读2w次,点赞51次,收藏33次。一、需求给定一个整数,返回大于等于该整数的最小2次幂(2的乘方)。例: 输入 输出 -1 1 1 1 3 4 9 16 15 16二、分析当遇到这个需求的时候,我们可能会很容易想到一个"笨"办法:..._整数 最小的2的几次方

Linux 中 ss 命令的使用实例_ss@,,x,, 0-程序员宅基地

文章浏览阅读865次。选项,以防止命令将 IP 地址解析为主机名。如果只想在命令的输出中显示 unix套接字 连接,可以使用。不带任何选项,用来显示已建立连接的所有套接字的列表。如果只想在命令的输出中显示 tcp 连接,可以使用。如果只想在命令的输出中显示 udp 连接,可以使用。如果不想将ip地址解析为主机名称,可以使用。如果要取消命令输出中的标题行,可以使用。如果只想显示被侦听的套接字,可以使用。如果只想显示ipv4侦听的,可以使用。如果只想显示ipv6侦听的,可以使用。_ss@,,x,, 0

conda activate qiuqiu出现不存在activate_commandnotfounderror: 'activate-程序员宅基地

文章浏览阅读568次。CommandNotFoundError: 'activate'_commandnotfounderror: 'activate

Kafka 实战 - Windows10安装Kafka_win10安装部署kafka-程序员宅基地

文章浏览阅读426次,点赞10次,收藏19次。完成以上步骤后,您已在 Windows 10 上成功安装并验证了 Apache Kafka。在生产环境中,通常会将 Kafka 与外部 ZooKeeper 集群配合使用,并考虑配置安全、监控、持久化存储等高级特性。在生产者窗口中输入一些文本消息,然后按 Enter 发送。ZooKeeper 会在新窗口中运行。在另一个命令提示符窗口中,同样切换到 Kafka 的。Kafka 服务器将在新窗口中运行。在新的命令提示符窗口中,切换到 Kafka 的。,应显示已安装的 Java 版本信息。_win10安装部署kafka

【愚公系列】2023年12月 WEBGL专题-缓冲区对象_js 缓冲数据 new float32array-程序员宅基地

文章浏览阅读1.4w次。缓冲区对象(Buffer Object)是在OpenGL中用于存储和管理数据的一种机制。缓冲区对象可以存储各种类型的数据,例如顶点、纹理坐标、颜色等。在渲染过程中,缓冲区对象中存储的数据可以被复制到渲染管线的不同阶段中,例如顶点着色器、几何着色器和片段着色器等,以完成渲染操作。相比传统的CPU访问内存,缓冲区对象的数据存储和管理更加高效,能够提高OpenGL应用的性能表现。_js 缓冲数据 new float32array

四、数学建模之图与网络模型_图论与网络优化数学建模-程序员宅基地

文章浏览阅读912次。(1)图(Graph):图是数学和计算机科学中的一个抽象概念,它由一组节点(顶点)和连接这些节点的边组成。图可以是有向的(有方向的,边有箭头表示方向)或无向的(没有方向的,边没有箭头表示方向)。图用于表示各种关系,如社交网络、电路、地图、组织结构等。(2)网络(Network):网络是一个更广泛的概念,可以包括各种不同类型的连接元素,不仅仅是图中的节点和边。网络可以包括节点、边、连接线、路由器、服务器、通信协议等多种组成部分。网络的概念在各个领域都有应用,包括计算机网络、社交网络、电力网络、交通网络等。_图论与网络优化数学建模

随便推点

android 加载布局状态封装_adnroid加载数据转圈封装全屏转圈封装-程序员宅基地

文章浏览阅读1.5k次。我们经常会碰见 正在加载中,加载出错, “暂无商品”等一系列的相似的布局,因为我们有很多请求网络数据的页面,我们不可能每一个页面都写几个“正在加载中”等布局吧,这时候将这些状态的布局封装在一起就很有必要了。我们可以将这些封装为一个自定布局,然后每次操作该自定义类的方法就行了。 首先一般来说,从服务器拉去数据之前都是“正在加载”页面, 加载成功之后“正在加载”页面消失,展示数据;如果加载失败,就展示_adnroid加载数据转圈封装全屏转圈封装

阿里云服务器(Alibaba Cloud Linux 3)安装部署Mysql8-程序员宅基地

文章浏览阅读1.6k次,点赞23次,收藏29次。PS: 如果执行sudo grep 'temporary password' /var/log/mysqld.log 后没有报错,也没有任何结果显示,说明默认密码为空,可以直接进行下一步(后面设置密码时直接填写新密码就行)。3.(可选)当操作系统为Alibaba Cloud Linux 3时,执行如下命令,安装MySQL所需的库文件。下面示例中,将创建新的MySQL账号,用于远程访问MySQL。2.依次运行以下命令,创建远程登录MySQL的账号,并允许远程主机使用该账号访问MySQL。_alibaba cloud linux 3

excel离散度图表怎么算_excel离散数据表格-Excel 离散程度分析图表如何做-程序员宅基地

文章浏览阅读7.8k次。EXCEL中数据如何做离散性分析纠错。离散不是均值抄AVEDEV……=AVEDEV(A1:A100)算出来的是A1:A100的平均数。离散是指各项目间指标袭的离散均值(各数值的波动情况),数值较低表明项目间各指标波动幅百度小,数值高表明波动幅度较大。可以用excel中的离散公式为STDEV.P(即各指标平均离散)算出最终度离散度。excel表格函数求一组离散型数据,例如,几组C25的...用exc..._excel数据分析离散

学生时期学习资源同步-JavaSE理论知识-程序员宅基地

文章浏览阅读406次,点赞7次,收藏8次。i < 5){ //第3行。int count;System.out.println ("危险!System.out.println(”真”);System.out.println(”假”);System.out.print(“姓名:”);System.out.println("无匹配");System.out.println ("安全");

linux 性能测试磁盘状态监测:iostat监控学习,包含/proc/diskstats、/proc/stat简单了解-程序员宅基地

文章浏览阅读3.6k次。背景测试到性能、压力时,经常需要查看磁盘、网络、内存、cpu的性能值这里简单介绍下各个指标的含义一般磁盘比较关注的就是磁盘的iops,读写速度以及%util(看磁盘是否忙碌)CPU一般比较关注,idle 空闲,有时候也查看wait (如果wait特别大往往是io这边已经达到了瓶颈)iostatiostat uses the files below to create ..._/proc/diskstat

glReadPixels读取保存图片全黑_glreadpixels 全黑-程序员宅基地

文章浏览阅读2.4k次。问题:在Android上使用 glReadPixel 读取当前渲染数据,在若干机型(华为P9以及魅族某魅蓝手机)上读取数据失败,glGetError()没有抓到错误,但是获取到的数据有误,如果将获取到的数据保存成为图片,得到的图片为黑色。解决方法:glReadPixels实际上是从缓冲区中读取数据,如果使用了双缓冲区,则默认是从正在显示的缓冲(即前缓冲)中读取,而绘制工作是默认绘制到后缓..._glreadpixels 全黑