第一周题单
D - 活动安排 (LibreOJ - 10000)
设有 n n n 个活动的集合 E = { 1 , 2 , . . , n } E=\{1,2,..,n\} E={1,2,..,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动 i i i 都有一个要求使用该资源的起始时间 s i s_i si 和一个结束时间 f i f_i fi,且 s i < f i s_i<f_i si<fi。如果选择了活动 i i i ,则它在时间区间 [ s i , f i ) [s_i,f_i) [si,fi) 内占用资源。若区间 [ s i , f i ) [s_i,f_i) [si,fi) 与区间 [ s j , f j ) [s_j,f_j) [sj,fj)不相交,则称活动 i i i 与活动 j j j 是相容的。也就是说,当 f i f_i fi ≥ s j s_j sj 或 f j f_j fj ≤ s i s_i si 时,活动 i i i 与活动 j j j 相容。选择出由互相兼容的活动组成的最大集合。
Input
第一行一个整数 n n n;
接下来的 n n n 行,每行两个整数 s i s_i si 和 f i f_i fi。
Output
输出互相兼容的最大活动个数。
Simple1
Input
4
1 3
4 6
2 5
1 7
Output
2
Note
1≤n≤1000
题解过程
活动安排问题要用贪心算法,对于贪心算法本题我们可以从三个方面入手,分别是1.开始时间、2.结束时间、3.时间跨度,显然从1、3入手是不可取的,因为开始时间就算再早但活动迟迟不结束,那么后面也无法容纳更多的活动,所以从这方面入手也没有什么意义,而时间跨度再短但结束时间与其他活动的开始时间不相容也没有什么意义
因此我们要从结束时间这一点入手,先对结束时间进行升序排序,因为活动结束的越早那么后面可以进行的活动就越多,至于结束时间的相同的活动怎么排序就无所谓了,然后就遍历排序好的数组,计算相容的活动数就好
#include <iostream>
#include <algorithm>
using namespace std;
struct activity
{
int s, f;
};
bool cmp(activity a, activity b)
{
if (a.f == b.f)
return a.s < b.s;
//return a.s > b.s;
return a.f < b.f;
}
void solution()
{
int n;
cin >> n;
activity a[n];
for (int i = 0; i < n; i++)
{
cin >> a[i].s >> a[i].f;
}
sort(a, a + n, cmp);
int temp = a[0].f;
int num = 1;
for (int i = 1; i < n; i++)
{
if (temp <= a[i].s)
{
temp = a[i].f;
num++;
}
}
cout << num << endl;
}
int main(int argc, char const *argv[])
{
solution();
return 0;
}
刚开始学习,欢迎指正