题目链接
题目梗概
有若干场比赛,每场比赛的时间为ai和bi,求在比赛时间不冲突的情况下,能参加的比赛场数最多为多少。
解题思路
考虑从早到晚来安排比赛,比赛时间结束越早,则我们之后能安排的比赛理论上就越多。所以首先先对比赛进行排序,结束时间早的优先。
设d[i]
为i
时刻之前能安排最多比赛数,则对于一场比赛而言,参加它后达到的最多比赛数为d[end] = d[begin] + 1
(加的一即为本次比赛)。
做法就是从早到晚遍历所有时刻,如果当前时刻没有比赛,则该时刻之前能安排的最多比赛书与上时刻相同,即d[i] = d[i-1]
。而如果当前时刻有比赛,则看安排下该比赛后是否会最多比赛数增大,若增大则更新数据。即d[i] = max(d[i], d[begin] + 1)
。
这里之所以遍历时刻而不是遍历比赛的原因是,要确保每一个时刻都有数据,避免出现中间某些时刻数据为0,而且也更符合该思路的逻辑。安排比赛是在时间线上安排的,可以通过画线作图的方式加以理解。
完整代码
#include <iostream>
#include <algorithm>
using namespace std;
struct contest{
int begin,end;
}c[1000001];
int d[1000001] = {0};
bool cmp(contest a,contest b){
if(a.end != b.end) return a.end < b.end;
else return a.begin > b.begin;
}
int main(){
int n;
cin >> n;
for(int i = 0;i<n;i++){
cin >> c[i].begin >> c[i].end;
}
sort(c,c+n,cmp);
int ans = 0,idx = 0;
for(int i = 1;i<=1000000;i++){
d[i] = d[i-1];
while(i == c[idx].end){
d[i] = max(d[i], d[c[idx].begin] + 1);
++idx;
}
ans = max(ans, d[i]);
}
cout << ans;
return 0;
}