本文主要做为本身的学习笔记,并不具有过多的指导意义。
贪心算法一般用来求解最优问题node
由局部最优解到总体最优解git
经过不断对局部最优进行操做,最终达到总体最优算法
无后效性swift
后序操做,不会出现数据状态的回滚数组
和DP(动态规划)之间的联系bash
不少贪心问题能够经过DP进行求解dom
- 给出N个物体,第一个物体重量为Mi
- 尽可能选择最多的物品,总重不超过C
先将物品按照质量排序,而后依次放入每一个物品,直到总重量将超过C位置。ide
这里依次将剩余物品中质量最小的物品放入的过程,就是贪心的过程。学习
一类总过程代价,取决于子过程代价的问题测试
首先,若是咱们什么都无论直接两两合并:总计消耗48点体力
而后,咱们尝试排序后两两合并:总计消耗44点体力
最后,咱们尝试只将当前全部数据中最小的两个进行合并:总计消耗38点体力
构建一个小根堆,每次从堆顶推出两个元素合并。而且将合并都的元素追加进小根堆中便可。
具体证实的过程有必定难度,能够参考哈夫曼编码证实的过程。
以上的操做过程,也就是贪心的过程。他只保证单次合并所消耗的体力最优,而不在乎其余的数据该如何合并。
堆结构每每用来解决贪心的问题。由于贪心问题每每须要一个明确的指标,最大值或者最小值。
输入:
cost[]:每一个项目的花费
profits[]:每一个项目的利润(纯利润)
k:最多能作k个项目
w:表示初始资金
输出:
最后能够得到的最大钱数
说明:一次只能作一个项目,且作完一个以后立刻就能得到收益,能够支持作下一个项目
cost
与profits
中的元素依次合并成一个新的节点node
:public class Node {
public var c :Int //项目花费
public var p :Int //项目利润
public init(cost:Int,profit:Int) {
self.c = cost
self.p = profit
}
}
复制代码
项目花费
构建的小根堆
将全部node
依次放入
项目利润
构建的大根堆
从小根堆中依次弹出堆顶元素,直到node.c>w
(项目所需资金大于当前资金)
具体代码上,将小根堆数组removeFirs
t,而后将arr[0]与arr[arr.count-1]位置交换
。让小根堆对arr[0]位置元素向下调整
便可。
将小根堆中弹出的元素放入大根堆中(大根堆中即为当前可执行的项目)
具体代码上,将元素追加进大根堆数组末尾,并进行调整便可。
从大根堆中弹出堆顶元素,并将w += node.p
(执行收益最大的项目,而且更新当前资金)
具体代码上与第一步相似
该贪心过程总计执行k次,每一次执行都只须要关心小根堆中最小值,与大根堆中最大值便可。最后的w即为最大总资产。
在优先的时间内安排数量最多的会议
作一张图能够直观表示过程:
咱们将蓝色表示为待安排
,红色表示为已安排
,黑色表示为不可安排
咱们能够尝试几种不一样的贪心策略
显然不可行
显然也不可行
因而可知该方案是能够行的
代码也很简单,只须要关心当前有效数据内开始时间晚于当前会议结束时间
的结束时间最先
的一个数据便可。
func bestArrange(programs:[Program]) -> Int {
program.sort("end")//根据program.end进行排序
var res = 0
var current = 0
for p in programs {
if p.current > current { //开始时间晚于当前时间,不然做废
res += 1
current = p.end //开会,当前时间变成会议结束时间
}
}
return res
}
复制代码
贪心策略的数学证实一般很复杂,有能力能够去翻阅
这里推荐一种很方便的方式,对数器。
经过小样本大样本量的测试,证实贪心策略的正确性。
以排序算法的证实举例
var checkOK = true
for i in 0..<10000 {
var arr1 = generateRandomArray(size: 5, value: 20) //获取一个长度为10,最大值为20的随机数数组
var arr2 = arr1 //数组在swift里属于值类型,赋值动做会自动copy
let originalArr = arr1
arr1.sort()//必定正确的算法
radixSort(arr: &arr2, maxDigit: 2)
if arr1 != arr2 {
checkOK = false
print(originalArr)
print(arr2)
break
}
}
print(checkOK ? "比对成功":"比对失败")
复制代码
对于贪心问题,可能不必定存在一个必定正确的算法。那么咱们彻底能够不去比对结果是否一致,只要贪心策略的结果永远优于默认顺序得出的结果便可。
关于对数器的介绍能够参阅另外一篇