小A是一个卷王,小A为了在Codeforces上干翻最高3900+的t宝,于是立了一个flag,要在一年之内刷完Codeforces上评分超过1600的所有题,虽然小A的学校大一不能带电脑,但是小A熬夜在网吧刷题!
但是codeforce上的题很多,如果要刷完的话,平均下来小A每天要刷20+题,每一题有最佳开始时间,部分题的最佳开始时间可能会有重叠,只有在最佳开始时间准时开始的题才能准时结束,每一题根据难度不同,其所消耗时间也不同,那么请问小A如何选择最佳写题顺序从而解决最多的题?
输入格式
第一行输入小A今天的刷题数目n(0<n≤10000)n(0<n≤10000)
接下来有nn行数,每一行的第一个数为该题的开始时间a_i,ai,第二个数为该题的结束时间b_ibi,其中ii的范围为(0≤i≤n)(0≤i≤n)
输出格式
第一行输出小A今天的最大刷题数量
第二行输出小A所能解决的题的序号,每到题的之间相隔一个空格
输入输出样例
输入 #1复制
12 1 3 3 4 0 7 3 8 2 9 5 10 6 12 4 14 10 15 8 18 15 19 14 20
输出 #1复制
5 0 1 5 8 10
说明/提示
注意事项
- 题的序号是从0开始
样例解释
在样例中,样例有12个题的起始时间,题的序号从0开始,样例第一行输出为5,第二行为0 1 5 8 10 分别对应输入中的题的编号,对照输入的起始时间分别为1 3,3 4,5 10,10 15,15 19
思路:贪心,自己拿纸模拟一下,对结束的时间排序,然后看结束的时间是否小于下一个的开始时间,如果小于就存起来总数++,如果大于就不合题意继续往下找,存的是题目编号所以我们要写一个结构体来存他的编号,开始时间结束时间,最后利用小根堆来输出存的题目编号即可。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
using namespace std;
int n;
struct name{
int l,r,num;
};
bool cmp(name a,name b){
return a.r <b.r ;
}
int main(){
struct name a[10005];
cin>>n;
for(int i=0;i<n;i++){
int x,y;
cin>>x>>y;
a[i].l =x;
a[i].r =y;
a[i].num =i;
}
sort(a,a+n,cmp);
int con=0;
priority_queue <int,vector<int> ,greater<int> >q;//用小根堆来存题目编号
int e=0;//用e来存右边结束的时间,因为初始时间是0所以赋值0
for(int i=0;i<n;i++){
if(a[i].l >=e){//如果开始的时间大于上一个结束的时间
con++;
e=a[i].r ;//更新e
q.push(a[i].num );//把下标存入
}
}
printf("%d\n",con);
while(!q.empty() ){//当q不空时输出队头再删除队头
printf("%d ",q.top() );
q.pop() ;
}
return 0;
}