PTA兼容任务
题目描述
设有n个任务,其中每个任务有一个起始时间si和一个结束时间ei,且si<ei,同一时间只能完成一个任务。如果选择了任务i ,则它在时间区间 [si ,ei) 内占用资源。若区间 [si ,ei) 与区间 [sj, ej)不相交,则称任务 i 与任务 j 是相容的。那么,对于给定的任务时间区间,能互相兼容的最大任务个数是多少呢?
输入格式:
第一行一个整数n (1<=n<=1000) ;
接下来n行,每行两个整数si 和 ei。
输出格式:
互相兼容的最大任务个数。
输入样例:
4
1 3
4 6
2 5
1 7
输出样例:
2
思路
- 同一直线上,线段与线段有三种情况:包含,相交,相离(?)
- 包含:按题目需要,应取包在里面的线段
- 相交:
- 左相较于和右相较于只是站在一种不同角度上来看
- 在相离的线段进行挑选
- 按左端点还是右端点(甚至是线段长度(线段的三个要素))来选择线段?如果按左端点的话,取极端情况,如果这一条线段的右端点是直达空间的最右端,那么别的线段就可以散伙了
- 根据反证法,应取右端点进行排序
- 相离:可以使方案数加一,如果在一条线段的右边出现多个相离线段(这些线段的左端点都大于等于这一条线段的右端点)的话,一定要选这些线段中右端点最靠左的端点(节省空间,为了后续能容纳更多的线段)
- 总体思想:尽可能选择右端点靠左的端点
- 尝试:可以先画两条线段来进行比较或者一条线段和其他几条要添加的线段
代码
#include<iostream>
#include<algorithm>//sort的库
#include<stdio.h>
using namespace std;
typedef struct{
int l;
int r;
}node;
node segment[1001];
bool cmp(node a,node b)
{
return a.r<b.r;
}
int main()
{
int n;
cin>>n;
for(register int i= 0 ;i<n;i++)
{
cin>>segment[i].l>>segment[i].r;
}
sort(segment,segment+n,cmp);
int ans=1;//起始为1
int cur_r=segment[0].r;
for(register int i = 1;i<n;i++)
{
if(cur_r<=segment[i].l)//注意题目是半开半闭区间
{
cur_r=segment[i].r;
ans++;
}
}
cout<<ans;
}