1. 什么是贪心算法?
贪心算法(Greedy Algorithm)是一种在每一步选择中都采取当前状态下最好或最优(即最有利)的选择,从而希望导致全局最优解的算法设计范式。它并不从整体上考虑问题,而是做出在当下看来最好的决策。
简单来说,贪心算法遵循“短视”原则:走一步看一步,只求眼前最好,绝不回头。
⚠️ 贪心算法并不总能得到全局最优解,但针对具有“贪心选择性质”和“最优子结构”的问题,它能高效地得出正确答案。
2. 贪心算法的核心特性
| 性质 | 含义 |
|---|---|
| 贪心选择性质 | 问题的全局最优解可以通过一系列局部最优选择得到。也就是说,贪心选择不会影响后续子问题的解的最优性。 |
| 最优子结构 | 一个问题的最优解包含其子问题的最优解。这是动态规划和贪心算法共有的性质。 |
与动态规划不同,贪心算法不保存所有子问题的解,也不进行回溯。它通常更加简单、高效。
3. 贪心算法的一般步骤
-
问题分解:将原问题分解为若干个子问题。
-
贪心策略:确定在当前状态下如何做出局部最优选择(依据某个度量标准)。
-
求解子问题:每做一次贪心选择,问题规模缩小,继续对剩余子问题应用相同策略。
-
合并解:将所有局部最优解合并成原问题的解。
4. 经典贪心问题与实现
下面通过三个经典问题来演示贪心算法的实现。
4.1 活动选择问题(区间调度)
问题:有 n 个活动,每个活动有起始时间 s[i] 和结束时间 f[i]。同一时间只能参加一个活动,问最多能参加多少个活动?
贪心策略:每次选择结束时间最早且与已选活动不冲突的活动。
def activity_selection(activities):
"""
activities: list of (start, end)
返回最大可参加的活动数量及具体活动列表
"""
# 按结束时间升序排序
activities.sort(key=lambda x: x[1])
selected = []
last_end = -float('inf')
for s, e in activities:
if s >= last_end: # 不冲突
selected.append((s, e))
last_end = e
return selected
# 示例
acts = [(1, 4), (3, 5), (0, 6), (5, 7), (3, 9), (5, 9), (6, 10), (8, 11), (8, 12), (2, 14), (12, 16)]
result = activity_selection(acts)
print("选中的活动:", result)
print("最多活动数量:", len(result))
9501

被折叠的 条评论
为什么被折叠?



