序言
我之前虽然在上课时进行了已经算很多的练习,从简到难。但是实际上理论方面,我完全没有听懂,不知道什么时候用,怎么用,反正经常听见大佬们说贪心就好了,但是还是迷迷糊糊的,所以在这里进行一些小小的学习记录。
适用范围
我们都知道在求解一个问题的 可行解或者最优解(即是最优化)的题目时,我们往往可以运用 贪心算法 对此类问题进行求解。
贪心算法的基本知识点
-
定义
贪心算法,又称贪婪算法(greedy algorithm)是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的算法。
(以上定义摘自Wikipedia——贪心算法) -
具体解释
虽然每一步都已经尽力选择当前此步的最优解,但 当前最优解不一定是全局的最优解。不过某些特定的问题可以利用贪心算法求得其最优解或较优解的。(例如旅行商推销员问题,以及求图中的最小生成树,还有哈夫曼编码等等…)
我们其实从定义中就可以看出,贪心算法因为思想过分简单,而导致无法解决所有问题的缺点。所以在运用贪心算法时,需要验证是否都是全局最优解。
贪心算法的实现步骤
1、创建数学模型来描述问题。
2、把求解的问题分成若干个子问题。
3、对每一子问题求解,得到子问题的局部最优解。
4、把子问题的解局部最优解合成原来解问题的一个解。
(以上来源于Wikipedia——贪心算法)
经典运用算法
虽然这些算法因为广泛运用以至于很多人知道,但其本质思想就是贪心。
因为本人最近致力于复习树,所以只截取了树相关部分。
-
最小生成树
1、prim算法
Prim算法的每一步都会为一棵生长中的树添加一条边,该树最开始只有一个顶点,然后会添加 V-1个边。每次总是添加生长中的树和树中除该生长的树以外的部分形成的切分的具有最小权值的横切边。
Prim算法的时间复杂度为 O(E+V\log V)。
这个算法是在贪边,还是很好理解吧。
2、 kruskal算法
按照边的权重顺序(从小到大)将边加入生成树中,但是若加入该边会与生成树形成环则不加入该边。直到树中含有 V-1条边为止。这些边组成的就是该图的最小生成树。
Kruskal算法的时间复杂度为 E\log E。
这个算法就是在贪权重了,既然是最小生成树,那么我从一开始就奔着权重去。
也很好理解吧。
小小总结
反正就是保持我需要啥,我就使劲贪就对了。但是需要注意判断是否为全局最优解。
然后就没了。之前到底为什么没懂!!
题目我没有进行题解分析,大体都是把握住贪心方向,检查是否可以是全局最优解。就算不能拿满(毕竟大部分时候不是正解),还是可以贪局部分。打暴力的好助手。