贪心算法
理论基础
贪心算法基本概念
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。
贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择,选择的贪心策略必须具备无后效性,即某个状态以前的过程不会影响以后的状态,只与当前状态有关。
贪心算法基本思路
- 基本思想
贪心算法的基本思路是从问题的某一个初始解出发一步一步地进行,根据某个优化测度,每一步都要确保能获得局部最优解。每一步只考虑一个数据,他的选取应该满足局部优化的条件。若下一个数据和部分最优解连在一起不再是可行解时,就不把该数据添加到部分解中,直到把所有数据枚举完,或者不能再添加算法停止 。
- 贪心算法过程
- 建立数学模型来描述问题;
- 把求解的问题分成若干个子问题;
- 对每一子问题求解,得到子问题的局部最优解;
- 把子问题的解局部最优解合成原来解问题的一个解。
适合解决问题
l 适用问题
贪心策略适用的前提是:局部最优策略能导致产生全局最优解。
l 实现框架
从问题的某一初始解出发;
while (能朝给定总目标前进一步)
{
利用可行的决策,求出可行解的一个解元素;
}
由所有解元素组合成问题的一个可行解;
l 贪心策略的选择
用贪心算法只能通过解局部最优解的策略来达到全局最优解,因此,一定要注意判断问题是否适合采用贪心算法策略,找到的解是否一定是问题的最优解。
贪心算法的步骤
根据题意,确定贪心策略(局部最优能够到达全局最优)
整理数据
根据策略逐个搜索,得到问题的解
输出结果
经典贪心
最优装载问题
贪心策略:先装最轻的。(不一定得到全局最优解)
有n个物体,第i个物体的重量为wi(wi为正整数)。选择尽量多的物体,使得总重量不超过C。
算法分析
由于只关心选择的物品的最大数量(而不是最大重量,最大重量需要考虑动态规划DP),所以装重的物体没有装轻的物体划算。这里只需对n个物体按重量递增排序,依次选择每个物体直到装不下为止。
这是一种典型的贪心算法,它只顾眼前,却能得到最优解。
1 |
|
sort
函数的原理
sort
函数使用一种高效的排序算法(如快速排序、堆排序或内省排序)来对元素进行排序。内省排序(Introsort)是C++标准库中常用的排序算法,它结合了快速排序、堆排序和插入排序,能够在大多数情况下提供快速排序的效率,同时避免了最坏情况下的性能问题。
详解
- 快速排序(Quick Sort):一种分而治之的排序算法,平均情况下具有O(n log n)的时间复杂度,但在最坏情况下会退化为O(n^2)。
- 堆排序(Heap Sort):基于二叉堆的数据结构,具有O(n log n)的时间复杂度,即使在最坏情况下也能保证这个时间复杂度。
- 插入排序(Insertion Sort):对于小规模数据或几乎已排好序的数据非常高效,具有O(n^2)的时间复杂度,但在小数据集时表现良好。
内省排序的工作流程如下:
- 首先使用快速排序对数据进行排序。
- 如果快速排序递归深度过大,可能导致最坏情况的出现,此时切换到堆排序。
- 在排序的最后阶段,当子序列长度较小时,使用插入排序完成排序。
总结
sort(w, w+n)是一种高效、简单的方式,用于对C++数组进行排序。它利用了内省排序算法的优势,保证了大多数情况下的高效性和最坏情况下的稳定性能。通过指定数组的开始和结束指针,可以方便地对数组进行排序,并且可以通过自定义比较函数实现不同的排序规则。
一维贪心
P23004排队打水问题
有N个人排队到R个水龙头去打水,他们装满水桶的时间为T1,T2,…,Tn为整数且各(1)不相等,应如何安排他们的打水顺序才能使他们花费的时间最少?
\【算法分析】**
由于排队时,越靠前面的计算的次数越多,显然越小的排在越前面得出的结果越小(可以用数学方法简单证明,这里就不再赘述),所以这道题可以用贪心法解答,基本步骤:
将输入的时间按从小到大排序;
将排序后的时间按顺序依次放入每个水龙头的队列中;
统计,输出答案。
2 1
5 10
\贪心策略:使前面的人等的时间最短**
【参考程序】
1 |
|