一、两种重要算法思想: 动态规划,贪心算法算法
二、动态规划:性能
基本原理:动态规划英文名dynamic programming。其中pogramming指的是表格法,而非编写计算机程序。所以,能够初步得出动态规划的基本思想:将一个具备最优子结构性质的问题分红若干个子问题,在求解过程当中,记录下子问题的结果,存储在一个表格中,使得公共的子问题只须要计算一次。书中给出的基本原理:动态规划将问题分红若干个相互重叠的子问题,递归的求解子问题,保存子问题的解,再将它们的解组合起来,求出原问题的解。优化
从基本原理中能够看出动态规划须要知足两个条件,最优子结构和子问题重叠。编码
最优子结构:书中定义:问题的最优解由相关子问题的最优解组合而成,一个问题的最优解包含其子问题的最优解。典型的有背包问题和钢条切割我问题。所谓子问题就是一中组合,将一个问题分红许多子问题的集合。某个子问题转化为问题时,所须要的代价是固定的。spa
通常这类问题的解题过程:(本身总结)orm
画出子问题图(相似于逆拓扑排序的图,子问题必须在问题前面完成)排序
用数学表达式构建出问题的最优解和子问题最优解之间的代数表达式递归
一般采用自底向上的方法进行递归地求解问题的解,自底下上的含义是从最小的子问题求起。数学
保存每一步求出的子问题的最优解原理
利用计算出的信息构造一个最优解
三、贪心算法:
基本原理:从初始状态出发,每步都通过贪心选择,最终获得问题的最优解。
含义: 将每一步都当作是当前最佳的选择,作到局部最优化,直到没法选择为止。寄但愿于局部最优的选择可以致使全局最优解。
两个实例:最小生成树算法和单源最短路径算法,以及集合覆盖问题的贪心启发式算法。
prim算法:将集合A当作是一棵树,每次选择剩余的节点中与这棵树造成的边的权值最小的点加入到集合A中造成新的树,循坏调用该过程,知道全部的点都已经放入到集合A中。初始时随机选择一个节点放入到集合A中。
kruskal算法:在全部链接森林中两颗不一样树的边里面,找到权重最小的边(u,v),并将其加入到集合A中,循环调用该过程,直到全部的点已经放入到集合A中
贪心选择:当进行选择时,咱们直接做在当前问题看来是最优的选择,而没必要考虑子问题的解。这与动态规划不一样,动态规划当前问题依赖于较小的子问题。而贪心算法中作当前问题最优选择,这样每步以后只须要作一个子问题的解。
也必须知足最优子结构的性质,即一个问题的最优解包含其子问题的最优解。
那么,如何区分何时使用动态规划,何时使用贪心算法呢?
典型的两个问题,0-1背包和分数背包。二者都具备最优子结构性质,可是贪心算法只能用来求分数背包的问题,而不能用来求0-1背包的问题。即只有分数背包具备贪心选择性。
我得总结(不必定对):具备贪心选择性的一类问题是:每次作选择时只有性能不一样,而代价是同样的。那么这样每次的选择都是最好的,最终会获得最好的结果。
哈夫曼编码也使用贪心选择算法。每次选择待编码的字符都选择在剩余的字符中出现次数最多的