一、 学习内容
1. 总体:理解算法的设计、提出、实现;算法的特性;算法的时间/空间复杂度分析等;
2. 主要讲解的算法思想:
① 递归
② 分治法(检索、找最大最小元素、排序/分类、斯特拉森矩阵乘法)
③ 贪心方法(0/1背包问题(物品可分解)、带有限期的作业排序问题及用集合树实现)
④ 动态规划(多段图向前处理法和向后处理法、构造最优二分检索树、0/1背包问题(物品不可分割)、可靠性设计问题、流水线调度问题、货郎担问题)
⑤ 回溯法(八皇后问题、带有限期的作业排序(惩罚值)、子集和数问题)
⑥ 分支限界法(华容道/15迷问题、圆排列问题(非书上例题)
3. 其他概念:
① 算法时间复杂度及分析
② P问题、NP问题、NP完全问题、NP难问题;
4. 第一部分:课程简介及算法简介
① 算法的(共识)定义:A set of rules for solving problems in afinite number of steps.一系列解决问题的明确指令,在规定时间内给出输入,得到输出。
② 算法的特性:有限性、确定性、0或多个输入、一个或多个输出、可行性/有效性;不仅要求步骤是有限的,而且要求步骤合理。
③ 设计算法:掌握算法设计策略 分析算法:分析占用CPU时间、占用存储器空间表示算法:将算法用语言表示出来 确认算法:保证算法是正确的
④ 运行时间用基本操作的次数来衡量,有如下:1<㏒N ⑤ 渐近表示:O(n)等 ⑥ 渐进函数的性质 5. 第二部分:递归(不考) 6. 第三部分:分治法 ① 概念 ② 二分检索、时间复杂度、以比较为基础的检索算法时间上界 ③ 寻找最大最小元素(原来的算法、改进算法、时间复杂度、何时使用改进算法、何时使用原来算法) ④ 排序问题:直接插入排序、归并排序、改进的链接归并排序、时间复杂度 ⑤ 斯特拉森矩阵乘法:将n^3改进为n^2.81,理解思想即可 7. 第四部分:贪心方法 ① 贪心算法定义 ② 背包问题(物品可以分解):度量标准、算法、贪心解就是最优解证明 ③ 带有限期的作业排序:度量标准、算法、贪心解时最优解证明、可行调度表的证明、总体算法、更快的作业排序算法、集合树实现 8. 第五部分:动态规划 ① 定义、最优性原理、多阶段决策 ② 多段图求最短路径:向前处理法、向后处理法 ③ 构造最优二分检索树:定义、递推关系式及推理、算法、KNUTH提出的改进、改进后的时间复杂性O(n^2) ④ 0/1背包问题(物品不可分割):递推关系式、序偶对及支配原则、回溯找解、支配原则转化为算法、时间复杂度分析、加速思想 ⑤ 可靠性设计:递推关系式、序偶对 ⑥ 流水线调度问题:抢先调度、非抢先调度、处理流程、递推关系式、Johnson不等式、应用Johnson法则简化、得出调度方法 ⑦ 货郎担问题:递推关系式、时间复杂度分析 9. 第六部分:回溯法 ① 概念 ② 过程 ③ 解空间树的一些定义:问题状态、答案状态、解状态、状态空间 ④ 解空间树的生成:活节点、死节点、E-节点 ⑤ 按照生成方式分类:深度优先生成、广度优先生成、D-检索、回溯法步骤、形式化描述、效率估计 ⑥ 八皇后问题回溯算法 10. 第七部分:分支限界法 ① 分支限界法 ② LC-检索 ③ 结点成本函数 ④ 估计函数 ⑤ 15谜问题及树的生成 ⑥ 3 ⑦ LC检索算法基本步骤(入活节点表判断、出活节点表判断) ⑧ 带有限期的作业排序(惩罚值)树的生成 ⑨ c(x)=U时怎么办? ⑩ FIFOBB算法(先入先出的分支限界算法) ⑪ LCBB算法(LC检索分支限界算法) ⑫ 分支限界算法优缺点 ⑬ 非书上问题:圆排列问题 11. 第八部分:NP问题等 ① 易解问题 ② 难解问题 ③ 判定问题和优化问题 ④ P类问题 ⑤ NP类问题 ⑥ NP难问题 ⑦ NP完全问题 ⑧ cook定理 二、 考试相关 1. 选择题: 2. 简答题:15谜判断、求解递推关系式、一些定义、NP问题等、算法思想、不受限节点估计值 3. 证明题:常证明以下问题:贪心解是最优解、可行调度表与可行解、渐进函数证明、书后习题证明(抢先调度也适用、作业执行时间不相等也可以得到可行调度表、 4. 计算题 5. 设计算法 考试题设计算法出的是寻找一个单峰数组的单峰,定义如下:如果一个数组A[n],有A[1]A[m+1]>…>A[n],则m是单峰数组A[n]的单峰。已知A[n]是单峰数组,使用直接比较找单峰时最好情况下的时间复杂度?最坏情况下的时间复杂度?使用分治法设计算法,最好情况下的时间复杂度?最坏情况下的时间复杂度? (1) 直接比较的意思就是两两元素进行比较找单峰,即找到第一个比后面元素大的元素,在考试时,我认为是从第一个元素开始比较,最好情况下是单峰是第二个元素,要进行两次比较:A[1]A[3],但是刚才想到,第一个元素肯定不是单峰,所以最好情况下只需要比较一次即可,时间复杂度是O(1),最坏情况下是A[N-1]是单峰,所以要从A[2]比到A[N-1],比较n-2次,时间复杂度是O(N);直接比较算法(已知A是单峰数组)可以表示为: i<-2; while(i+1<=N){ if(A[i]>A[i+1])then return i; else i++; } return -1; (2) 分治法设计的算法: EC(low,high.p)//p是返回值,-1表示无单峰 if(high-low<=4) then{//数组规模小于5 i<-low+1; while(i+2<=high)do{ if(A[i]A[i+2])then return i+1; else i++; } return -1; } else{ mid<-(low+high)/2;//取地板操作 EC(low,mid+1.p1) if(p1!=-1) return p1; EC(mid-1,high.p2); return p2; } 上面算法的思想是每次将规模较大的A分成两部分,分别找单峰再一起判断,由于如果单峰在中间,即在mid处,如果按照传统的分治法分为(low,mid)、(mid+1,high),分成的两个数组将一个是递增的,一个是递减的,无法找到单峰,所以分成(low,mid+1)、(mid-1,high),两部分,若mid是单峰,则两个数组全都能找到它,所以在实际使用时,先找左边的单峰,没有才找右边的。 为什么用5作为数组是否使用分治法的分界?最开始我是想,因为规模为5的数组使用分治法,变成了两个规模为4的数组,如果单峰是第4个元素,那么就是在找两个4元数组的单峰,这样看分治法算法效率并不明显,所以选的5作为分界。 为什么在小于5的数组直接比较找单峰时和(1)不一样?因为(1)中数组肯定是单峰数组,而在(2)中不确定,有可能是一个依次递增的数组,也有可能是一个依次递减的数组,因此只比较相邻两个元素是不够的。 最好情况下就是规模<5,元素第二个,需要比较2次(第一个和第二个、第二个和第三个),时间复杂度是O(2); 最坏情况下,就是规模很大,而且倒数第二个元素是单峰,这时,每次使用分治法,都必须调用两次EC,设n=2^k*m(m=3,4,5); T(n)=2*T(n/2)+c=4*T(n/4)+2*c+c=…=2^k *T(m)+(1+2+…+2^(k-1))*c=2^k*b+(2^k -1)*c;其中b是n<=5是的时间复杂度,是一个常数,c是“合”的时候对于p1、p2判断的时间复杂度,也是一个常数,因此,最后最坏情况下的时间复杂度是O(n). 3.算法分析题型(分数不太记得了) ①选择*5(基本靠概念、时间复杂度等、NP问题方面必出一个) ②简答题*4 ③证明题*2(贪心解是最优解、渐进函数的证明、某些算法的推广和某一步骤的证明) ④计算题*4(带有限期的作业排序(集合树,考试考了)、0/1背包问题贪心方法和动态规划方法(考试考了)、流水线调度(考试考了)、最优二分检索树构成、XX谜问题(考试考了)、多段图问题、计算不受限节点估计) ⑤计算题:考试考的题见上面,平时遇到的有点意思的是分治法找假币、分治法判断二叉树是否对称同构