题意:N个线段,机器最多一次录K段,不重叠的可以连续录而不占用其他资源,问最多能录几段
思路:首先经典的贪心排序方法排序(按结束时间从小到大,如果结束时间相同,按起始时间从大到小)
我们可以想象有K个机器,那我们需要记录的就是第i个机器在什么时候才会有空
对于每一段[l,r],我们只需要查找这K个机器在l时间会不会有空,如果有的话,录这一段,更新结束时间,否则抛弃这一段(后面的段只会结束时间更晚,即使结束时间相同,也将占用更多时间)
所以我们开一个set,包含k个元素,记录K个机器的工作结束时间
起始的时候都是0,所以预处理set里要插入k个0
对于每一个询问[l,r],查找有没有元素小于或等于l,如果有的话,删掉该元素, 插入r(即上面的更新)

#include"cstdio" #include"queue" #include"cmath" #include"stack" #include"iostream" #include"algorithm" #include"cstring" #include"queue" #include"map" #include"set" #include"vector" #define ll long long #define mems(a,b) memset(a,b,sizeof(a)) #define ls pos<<1 #define rs pos<<1|1 using namespace std; const int MAXN = 100500; const int MAXM = 100500; const int INF = 0x3f3f3f3f; struct node{ int s,e; }seg[MAXN]; int n,k; multiset<int> x; bool cmp(node a,node b){ if(a.e==b.e) return a.s>b.s; return a.e<b.e; } void display(){ multiset<int>::iterator itt; for(itt=x.begin();itt!=x.end();itt++) cout<<*itt<<' '; cout<<endl; } int main(){ //freopen("in.txt","r",stdin); while(~scanf("%d%d",&n,&k)){ for(int i=0;i<n;i++) scanf("%d%d",&seg[i].s,&seg[i].e); sort(seg,seg+n,cmp); x.clear(); for(int i=0;i<k;i++) x.insert(0); multiset<int>::iterator it; int tot=0; for(int i=0;i<n;i++){ it=x.upper_bound(seg[i].s); if(it!=x.begin()){ tot++; it--; x.erase(it); x.insert(seg[i].e); } } printf("%d ",tot); } return 0; }