2021寒假算法学习
写在前面:下面内容都是2021春寒假学习算法时写的心得感悟与疑问。本来想整理一下做的习题的,由于做的习题太多难得整理。。。
-
day0:
- 卡特兰数
-
day1:
- 错排数
- 题目
P1595 信封问题
-
day2:
- 递推与递归只是思考顺序不同,但计算顺序是相同的,2种思维都要掌握
- 许多可以挖掘出一些自相似性的问题可以强行分治以用于降低复杂度。
- 分治的裸题一般不多,思想多用于高级数据结构中
- 题目
-
day3:
- 康托展开。(通过字典序的原理,数字映射到数字的排列数)
- bfs双向复杂度为单向bfs的根号(状态树层数少一半),双向bfs适用于初态和终态唯一确定的。
- 为什么八数码用iddfs会tle(重复状态太多),bfs和iddfs的升级搜索算法(a* 与 ida*)。iddfs与bfs复杂度同阶。(递增的等比数列)
- dfs序:一个节点的编号一定小于它的子节点,一颗子树中的结点的 dfs 序对应着一段连续的整数区间。与线段树的关系?
- 爆搜可用于找规律,然后发现正解
-
day4:
- 组合数学(进阶)。
- 定性的问题往往比定量的问题研究要简单,但也有反例。
- dfs和bfs用得挺多的。图大部分都用邻接表,邻接矩阵很少用。
- 技巧:图中建立反向边看能不能把问题转换简单。或者问题中反向思考看能不能转换问题。
- 欧拉图和哈密尔顿图无高效解法,只能爆搜(dfs)
-
day5:
- 排列的逆,可用数组下标进行映射,值域与定义域之间反复转换,容易绕晕,可画图模拟。
-
day6:
- 并查集只维护图的联通性,与节点之间的具体关系无关。
- 数组模拟链表可用数组记录节点的index加快查询,如果节点值是固定的,可以直接维护节点之间的链式信息以简化代码。
-
day7:
- 二分本质是函数具有单调性(参考零点定理),有序数组也可以看作值离散的函数。
- 二分答案的题目核心是抓住其中哪2个变量的变化情况具有单调性,而答案与这2个变量的单调性有关。
- 二分答案提示性关键词:“最大值最小”,“最小值最大”
- 贪心思想的应用:huffman编码,kruskal,dijkstra
-
day8
- 和自然数扯上关系的许多问题都可以用数学归纳法证明。(因为自然数集本身就是递归定义的)
- 拓扑序列的顺序和DP中状态转移的顺序一致
- 有向无环图(DAG)呈现出明显的层级关系,对DAG进行分层就是拓扑排序
- DAG和DP的关系
- 拓扑(Topology)主要研究物体间的位置关系,而不考虑它们的形状和大小。(eg:中学物理研究物体受力的质点,地图)
- 拓扑排序就是根据一些两个物品之间的顺序排出整个物品集合的顺序,更数学地说,是由一个集合上的偏序得到集合的全序。拓扑排序的过程非常类似于BFS,区别在于BFS是只要接触到后续状态就加入队列,而拓扑排序要求后续状态的先序状态都被遍历过后再加入。
- 树型DP的状态转移通常是以以dfs序的顺序
- 拓扑序和dfs序天然的具有DP的最优子结构性质?
-
day9
-
DP可以理解为”高级“的递推。严格意义来讲,DP是求解最优解的方法,但通常来说由于DP考虑了全部状态,所以DP也常常拿来解决计数问题。(但求解最优解时转移中可以取到重复状态,而计数问题转移中则不能取到重复状态)
-
问题状态空间感性理解:贪心:70%,DP:100%, 搜索:500%。速度:贪心>DP>搜索(百分比数值不是绝对关系)。拿01背包举例,贪心有可能会漏掉最优解,而dp不会。正是因为这种特性,所以贪心很容易漏解,需简单证明才写代码。搜索搜索状态空间往往是一个冗余的过程,先搜出大量状态,然后从中选择合法状态判断最优解,可行解等。
-
贪心与动态规划的比较:
- eg:凑硬币问题:给定一个面值n,求恰好凑出n元最少的硬币数。条件:有1,2,5元面值的硬币(贪心),有1,4,5元面值的硬币(DP)
- 动态规划要考虑这一步是所有可能情况,从之前的所有状态中选择一个最优解。
- 而贪心算法并不需要考虑所有可能情况,只要从当前的状态下选择一个最优解。
- 换而言之,贪心比较“目光短浅”,而动态规划更具有“全局意识”
-
设计状态时,状态必须要能唯一、确定地表达当前遇到的局面!否则会有后效性
现在的决策,只与过去的结果有关,而与过去的决策无关。也就是说当前状态由前面状态的(值)推出,与前面状态是怎么计算出来的无关。
-
-
其他
- 数组下标与数组中的值可以看作函数的定义域与值域,只不过定义域是建立在自然数集上,而值域建立在整数集上。
- 定义域为正整数集的函数称为数论函数