题目:
假定有集合S个活动S={a1,a2,a2...an},对于每个活动的开始与结束时间为s={s1,s2,s3...sn},f={f1,f2,f3..fn};求在不重复时间段里可以利用的场地最大化(活动最多)的解。
而我们使用贪心算法就是将大事化小,小事化了的方式去解决问题,对于本题我们有三种思路去小事化:(网上资料图)
但我们会发现前两种策略显然不是最优,都会有反例可以推翻,那么第三种如何得出符合我们的要求呢?
显然由图可知,我们可以先对结束时间进行排序(开始时间相对应一起),那么第一个肯定就是最早结束的活动即f1最小,那么就要排除与f1时间相重复的s1都应排除(不可选),而要找si>=f1的活动开始时间(因为已经排过序了就直接遍历往后找第一个符合的就行)。以此类推,处理完所有活动时间。
代码大致如下(可参考)
#include<bits/stdc++.h>
using namespace std;
typedef struct NNN {
int s;//开始
int f;//结束
}fs;
bool cmp(fs a, fs b) {
return a.f < b.f;
}
int main() {
int t, n;
cin >> t;
while (t--) {
cin >> n;
fs d[1000];
for (int i = 0; i < n; i++)
cin >> d[i].s >> d[i].f;
sort(d, d + n, cmp);
int con = 1,/*至少有一个活动可参加*/ endt = d[0].f;
for (int i = 1; i < n; i++) {
if (endt <= d[i].s) {
con++;
endt = d[i].f;
}
}
cout << con << endl;
}
}
伪代码:
本篇博文主要解析了活动选择的思路,如果小伙伴们感觉还是不太懂的话菜菜推荐看看这个视频:(冲鸭)【持续更新】算法设计与分析 - 北航童咏昕教授_哔哩哔哩_bilibili