贪心算法
概念讲解
什么是贪心?
贪心算法是一种在每一步都选择当前最优解的算法策略。
贪心的条件
- 贪心选择性质: 局部最优能导致全局最优
- 最优子结构: 问题的最优解包含子问题的最优解
经典模型
1. 活动选择问题
问题: n 个活动,每个有开始和结束时间,求最多能参加多少个活动。
策略: 按结束时间排序,每次选最早结束的。
12345678910111213int activitySelection(vector<pair<int,int>>& activities) {
sort(activities.begin(), activities.end(), [](auto& a, auto& b) {
return a.second < b.second;
});
int count = 0, lastEnd = 0;
for (auto& [start, end] : activities) {
if (start >= lastEnd) {
count++;
lastEnd = end;
}
}
return count;
}2. 区间调度问题
策略: 按右端点排序。
3. 分糖果问题
策略: 排序后一一匹配。
考点分析
初赛考查方式
- 选择题: 贪心策略
- 程序阅读: 贪心程序
- 编程题: 贪心应用
常见考点
- 贪心策略设计
- 排序贪心
- 区间问题
例题精讲
例题 1:活动选择
题目: 活动 [(1,3), (2,5), (4,7), (6,8)],最多能参加几个?
解答:
按结束时间排序:(1,3), (2,5), (4,7), (6,8)
选 (1,3) → (4,7) → 最多 2 个。
例题 2:分糖果
题目: 孩子需求 [1,2,3],糖果大小 [1,1,3],最多满足几个?
解答:
排序后匹配:1→1, 2→不满足, 3→3 → 最多 2 个。
练习题
- 贪心算法的两个条件是什么?
查看答案
- 贪心选择性质:局部最优选择能导致全局最优解
- 最优子结构:问题的最优解包含子问题的最优解
- 活动选择问题的贪心策略是什么?
查看答案
按结束时间排序,每次选最早结束的活动。
因为结束越早,留给后面活动的时间越多,能参加的活动数量就越多。
- 贪心和动态规划的区别是什么?
查看答案
| 特性 | 贪心 | 动态规划 |
|---|---|---|
| 选择方式 | 每步选当前最优 | 考虑所有子问题 |
| 是否回溯 | 不回溯 | 可能需要回溯 |
| 正确性 | 需要证明贪心选择性质 | 一定正确(最优子结构) |
| 效率 | 通常更快 | 可能较慢 |
贪心适用于局部最优能导致全局最优的问题,DP 适用于有重叠子问题和最优子结构的问题。两者都要求无后效性。
易错点
⚠️ 注意:
- 贪心不一定能得到最优解
- 需要证明贪心策略的正确性
- 排序是贪心的常见预处理
- 贪心和 DP 的区别:贪心每步选局部最优且不回溯,DP 考虑所有子问题