算法总结

贪心算法

  • 解决问题:最优化问题;

  • 优点:是解决最优化问题的最优策略,时间复杂度低;

  • 缺点:要满足局部最优解可以推出全局最优解,这意味着在考场上想出一个贪心策略需要通过举例以及证明。

  • 常见思考方式:

    • 如果是决定谁先做谁后做的,类比排队问题,邻项交换;如果先后有限制关系,比如谁先做谁后做,那么通常套路还是找出最优的,尽可能合并,或者直接将限制的直接干掉。

    • 对于树上问题,通常考虑从下到上进行合并。

    • 区间问题,首先将区间左/右端点进行排序,然后考虑怎么处理。

    • 更为一般的问题,如果几种策略的贡献相等,就考虑对于后面的影响。

    • 对于每个必选的,直接考虑每个点如何加入。

    • 实在不会,考虑反悔贪心。

搜索

深搜优化

  • 剪枝

    • 可行性剪枝;

    • 最优性剪枝;

    • 优化搜索顺序;

    • 减少冗余状态;

  • 迭代加深搜索

    • 适用范围:不知道明确的搜索边界,或者做搜索树的简单优化;

    • 可以达到广搜第一次搜到就是最优解的效果;

  • \(IDA^*\) 算法

    • 注意:估价函数 \(f()\) 一定要 \(\le\) 真实值,约接近效率越高。

    • 适用范围:比较容易得出估价函数的题目。

广度优先搜索

  • \(bfs\)

    • 适用范围:边权相等,最优化问题,第一次搜到就是最优;

    • 优点:在时间常数上,广搜最优,所以对于信息容易放进队列的题目,宜用广搜;

    • 缺点:由于必须将信息存进队列,因此若信息过大,则无法放进队列,这时只能深搜。

二分

  • 适用范围:具有单调性的最优性问题,求最大值最小/最小值最大,排名,变化后的数字。

  • 注意:

    • 合理选取二分写法,否则造成死循环;

    • 如果 \(l,r\) 特别大,考虑加在一起会不会爆 \(int\)

  • 优点:可以将最优性问题转化为可行性问题,然后利用条件进行一系列简化。

  • 思考方向:

    • 利用二分出来的值进行分段 ;

    • 利用 \(mid\) 将已知条件进行重新赋值,比如赋值 \(0,1,-1\) 这种较具代表性的数。

线性表

  • 概念:先进后出的数据结构;

  • 适用范围:

    • 表达式求值。

      • 两个栈,一个数字栈,一个符号栈,遇到数字就往数字栈里面塞,遇到符号,如果这个符号比栈顶符号的优先级大,直接将数字栈弹出了两个算出结果再塞回去,这个符号就不放回去了。否则将符号塞进去,若是遇到左括号,直接塞,遇到右括号,将数字栈和符号栈轮流弹出,直到遇到左括号为止。在将结果塞回去。
    • 括号匹配

      • 左括号就塞进栈,右括号就将顶上的括号弹出,然后标记那两对是匹配的,一般还会结合 \(dp\) 进行出题,这时需要利用匹配结果进行转移。

并查集

  • 适用范围:

    • 维护图的连通性;

    • 维护某种关系;

      • 如果是关系较多,考虑扩展域并查集。
    • 实现快速找到第一个没有填数字的位置。

      • 对于某类区间操作的题目,考虑时间倒流加并查集操作。

前缀和与差分

倍增

  • 适用范围:

    • 对于一步一步跳并统计贡献的暴力,尝试用倍增对其优化。

图论

拓扑排序

  • 适用范围:在 \(DAG\)\(dp\) 或者计算;

欧拉路径

  • 使用范围:图论建模后,不重复且全部走完边的方案。

  • 概念:从一个点出发,不重复地走边,将所有边走完,最后回到一个点;

  • 有向图:

    • 欧拉路径:要么全部节点入度等于出度,要么有一个节点出度等于入度 \(+1\)(起点),一个节点的入度等于出度 \(+1\)(终点),其他节点的入读等于出度。

    • 欧拉回路:全部节点入度等于出度。

    • 注意:当前弧优化。

  • 无向图:

    • 类似有向图,此处只需考虑节点度数的奇偶性即可。

    • 注意:无向图只能写邻接表存图,否则要用 map 对边进行标记,效率很低。

  • 思考方向

    • 这种题通常会有不能重复,且首尾有些关系的条件,这时要将关键信息放在边,其他信息放在点。

    • 可以利用欧拉路径将若干简单环构成的图,进行分解,得到这些环。

最短路

最小生成树

  • 概念:在图中边权和最小的一棵树。

  • 适用范围:

    • 找出一颗最小生成树,只是贡献的计算有点奇怪;

    • 希望边权尽可能的大/小,可以在图上找一棵最小/大生成树;

    • 利用 \(kruskal\) 的性质出题,只需掌握合并的规律即可。

联通性问题

  • 强连通分量

    • 适用范围:有向图。

    • 常见功能:

      • 将一个有向图转化成一个 \(DAG\)

      • 能缩点的题目,通常对于环的处理都很简单,唯一困难就是在 \(DAG\) 的递推上。

    • 易错点

      • 要记得写 is_stack 数组,在满足 dfn[x]!=0 时,先判断 is_stack[x] 再更新 low[nd]

      • 如果不是先 tarjan 的,要用 dfn[x] 更新 low[nd]

  • 边双连通分量

    • 适用范围:无向图。

    • 常用功能:

      • 将一个无向图转化为一棵树;

      • 缩边的题目通常上在题目描述上会特别描述,因为变成树以后,所有边都是桥,也就是必须经过的边。

树论

树的直径

  • 概念:树上一条最长链。

  • 求解:

    • 两边 dfs 可以求出树的直径。

    • 若要求出树的直径上的点,设置上一个节点然后往回跳即可。

  • 性质

    • 与一个点距离最远的点,一定是树的直径端点;

    • 若树边权为正,则所有树的直径必定有点重合,即没有不相交的两个树的直径。

树的重心

  • 概念:使得以该点为根的最大子树最小的点。

  • 性质:

    • 树中所有点到重心的距离和是最小的。

    • 重心的最大子树大小不超过整棵树大小一半。

最近公共祖先

  • 求法:倍增,树剖。

  • 基本上树上问题统计贡献或是判定问题都可以在 \(LCA\) 处解决。

树链剖分

  • 概念:根据轻重儿子将树剖分成一条条轻重链。

  • 维护各种树上信息。

字符串

border

  • 概念:最长相等前后缀。

  • 性质:

    • 字符串 \(s\)\(border\)\(border\) 还是自己的 \(border\)

    • 在原来字符串后添加一个字符,字符串的 \(border\) 长度至多加 \(1\).

    • 周期:除去 \(border\) 剩下的就是周期。

  • 常考题目

    • 利用 \(border\) 性质进行出题,一般涉及周期,相同字母覆盖,以及一些失配树的相关问题。

    • 利用 \(border\) 的性质实现 \(dp\) 转移。

kmp

  • 性质:利用 \(border\) 计算出失配数组,便可以在 \(\rm O(n)\) 时间内完成匹配。

哈希

  • 使用范围:要对子串进行一定程度的匹配,如果单纯是对整个字符串进行匹配,直接 map 即可。

  • 注意:在考场上为了保险,最好写双哈希

字典树

  • 适用范围:

    • 字符串字典树:进行前缀信息匹配,以及相关计算;

    • 01字典树:进行 \(xor\) 相关计算,具有求出排名为第 \(k\) 大的异或值。

  • 常见技巧:

    • 在字典树上标记通常有两种,一种是直接在最后标记,这样计算完全匹配;一种是在过程中的节点标记,这样可以计算匹配前缀。
  • 注意:字典树的空间小号算是比较大的,清空时记得清空 \(tot\)

posted @ 2023-11-16 20:28  2017BeiJiang  阅读(8)  评论(0编辑  收藏  举报