教学目标:掌握蛮力、分治、减治、变治和时空权衡等算法设计思想的特点
- 蛮力:直接基于问题描述和涉及概念,常用于小规模例子,给出一个问题解的时间复杂度上界,衡量其它算法的时间效率,唯一一个能够应用于所有问题的策略。
- 分治:划分大问题为多个小问题并解决合并。
- 减治:大规模问题简化为一个小问题。
- 变治:转换问题或数据结构。
- 时空权衡:空间和时间的选择。
能够熟练使⽤蛮力法解决问题,作为优化的基线⽅法
找到最接近元素的差
找到凸包极点(顶点)
p2-p1 和 p3-p1 两个向量,夹角为锐角则叉积为正左侧,否则钝角为负右侧,直角为 0。
分治思想在具体实现的时候,可以使⽤递归的⽅法,也可以结合特殊的数据结构使⽤循环的⽅法
合并排序根据位置分组,快速排序根据值分组。
合并排序
快速排序
能够采⽤分治思想解决的两个经典问题是最近对问题和凸包问题,请掌握具体的代码实现
最近对问题
凸包问题
难点:合并两个凸包,先找到左凸包中最右的点和右凸包中最左的点,然后找上下共线点。
时空权衡思想在算法设计中应⽤非常⼴泛,例如字符串匹配、B 树,乃至动态规划
字符串匹配
Horspool
如果只用坏符号移动表或者好后缀移动表,BM 算法能够正确工作吗?为什么要一起使用?
只用坏符号移动表和好后缀移动表都可以正确工作,只是效率降低。
B 树
贪心法
最小生成树
Prim:从点开始贪心选择。
Kruskal:从边开始贪心选择。
Dijkstra:不断更新未访问点的最短路径和。
活动相容
按照结束时间升序排列,依次选择靠前结束的,尽可能给后面留出更多时间余量执行更多活动。
动态规划
最长公共子序列
最长回文子序列
矩阵连乘
求多个矩阵连乘的最小次数。
了解平滑函数性质,能⽤主定理求解递归⽅程,判断当前⽅程适⽤主定理哪⼀类型,进而解出递归式
T(n)=2T(n/2)+nlogn 不符合三种情形中的任意一种,因此:
复杂度的表示法:O(f)、Ω(f)和 Θ(f)的含义,基于三种表示的⼀系列性质
对于两个函数 f(n) 和 g(n),如果存在正数 c 和正整数 n0, 使得对于所有n≥n0,都有f(n)≤c⋅g(n), 那么 f(n)=O(g(n)) 。
对于两个函数 f(n) 和 g(n),如果存在正数 c 和正整数 n0, 使得对于所有n≥n0,都有f(n)≥c⋅g(n), 那么 f(n)=Ω(g(n)) 。
对于两个函数 f(n) 和 g(n),如果存在正数 c1 、c2 和正整数 n0, 使得对于所有n≥n0,都有c1⋅g(n)≤f(n)≤c2⋅g(n), 那么 f(n)=Θ(g(n)) 。
介绍 NPC 理论的含义和实际应⽤价值,能列举 NPC 问题,证明⼀些主要的 NPC 问题(如装箱问题,0-1 背包)既是 NP 的也是 NP-hard 的
首先证明 NP,然后证明 NPH。
装箱问题:
近似算法的定义,如何衡量近似算法的好坏,能掌握对于装箱问题的几种贪⼼算法(First Fit Algorithm - FF,Next Fit Algorithm - NF,First Fit Decreasing - FFD)。 在线算法的定义,以上哪个算法是在线算法,复杂度如何
FFD,不是在线算法,FF 和 NF 是在线算法。
在线分箱的定义:
- 条目是一个接一个输入的,这意味着算法在输入结束前永远不知道输入何时结束。
- 对于装箱,每个条目都必须先放入一个箱,然后才能处理下一个条目。
- 由于输入可能在任何时候结束,因此,任何最优解在任何时候都应该是已处理输入的最优解。
在最坏的情况下,任何在线分箱打包算法都至少使用最佳分箱数的 4/3。证明:先 n 个(1/2-ε),然后 n 个(1/2+ε)。
需要注意的是,没有两个连续的分仓可以包含总值小于 1 的对象,这意味着最多浪费一半的空间。
存在 NF 使用 2m-2 bins 的输入。
举个例子输入序列 S 由 n 个项目组成(对于某个整数 k,n=4k)。奇数 i 的 si 大小为 0.5,偶数 i 的 si 大小为 2/n。
最佳的分仓数为 n/4+1(n/4 表示 2 个大小均为 0.5 的分仓,1 表示所有大小为 2/n 的分仓)。
NF 使用 n/2 个分仓。
NF 复杂度O(n)。