解题思路
使用贪心算法来解决这个问题。首先将活动按照结束时间从小到大进行排序,然后依次选择结束时间最早的活动判断是否能加入到最大集合中并进行相应的计数。大致证明如下:
假设总共有m项活动,已经检查了n项活动,若要选取n+1项活动并判断其是否能加入最大集合,则应当保证他的结束时间尽量早,这样在检查第n+2及其后面活动时就更有机会被选取。因此在选取第n项检查时,应当选取剩余项目中结束时间最早的。
因此大致流程如下:
-
排序:将活动按照结束时间从小到大进行排序。(实际实现的时候偷懒用了multimap,没有使用sort函数排序)
-
初始化计数器:设置一个计数器,表示最大集合中活动的个数,初始值为 1。
-
遍历活动:从第二个活动开始遍历排序后的活动列表。
- 如果当前活动的起始时间大于等于上一个活动的结束时间,则将当前活动加入到最大集合中,并更新计数器的值加 1。
-
输出结果:输出计数器的值,即互相兼容的最大活动个数。
满分代码
#include <iostream>
#include <map>
using namespace std;
int main()
{
int num;
scanf("%d", &num);
multimap<int, int> data;
for(int i = 0; i < num; i++)
{
int head,tail;
scanf("%d %d",&head, &tail);
data.insert(make_pair(tail,head)); //将结束时间作为键值储存,省去排序步骤
}
int cont = 1;
auto it = data.begin(); //定义迭代器
it++;
auto it2 = data.begin();
for(auto it_pre = it2->first; it != data.end(); it++)
{
if(it->second >= it_pre) //判断后一项活动开始时间是否小于前一项结束时间
{
cont++;
it_pre = it->first;
}
}
printf("%d", cont);
return 0;
}