bzoj 2474

题目内容:

Description

A经常会收到很多的定单。定单的内容为在第a天到第b天**团队将要在A的公司狂欢(包括第a天与第b天)。一旦接受了某一个定单,A公司就必须在第a天到第b天为该团队提供娱乐服务,中途不能取消服务。要如何安排才能使得接受的定单最多呢?
现在告诉你A公司最多能同时服务的的团队数目以及收到的所有定单,求出可以接受的定单的最大值。

Input

文件的第一行包含一个整数T,表示数据组数。
对于每组数据,第一行包含两个整数n和m,分别表示收到的定单数和公司能同时服务的团队数。接下来n行每行包含两个整数a和b,表示一个定单的内容:某个团队将在第a天与第b天之间在A公司进行狂欢。

Output

对于每组数据输出一行。该行仅包含一个整数,表示最多能接受的定单数。

题解:看到题目,我们知道这是一道高级版的线段覆盖,想法:贪心。

          我们可以从左往右做,这样的话,左边的影响处理好了,对于某一个地方超过了m,我们这些之中右区间最大的删去,因为它的影响最大,而它们对左边的影响是一致的,所以删去右区间最大的就可以了。 复杂度就是(n*log(n)) (删去的右区间最大的删法,我们可以用一个堆来维护加进去的订单,这样每一个订单进入一个堆一次,最多出去一次)

#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int N=1E5+20;
bool h[N];
struct com{
	int a,b,c;
	bool operator <  (const com & x)const{
		return b<x.b;
	}
	bool operator >(const com &x) const{
		return b>x.b;
	}
}a[N];
bool cmp(com x,com y){
	return x.a<y.a||(x.a==y.a&&x.b<y.b);
}
int main(){
	//freopen("1.in","r",stdin);
	//freopen("1.out","w",stdout);
	int T;
	scanf("%d",&T);
	while(T--){
		int n,m;
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++){
			scanf("%d%d",&a[i].a,&a[i].b),h[i]=0;
			if(a[i].a>a[i].b){
				int t=a[i].a; a[i].a=a[i].b; a[i].b=t;
			}
		}
		sort(a+1,a+n+1,cmp);//将订单按左区间排序,一个个处理
		for(int i=1;i<=n;i++) a[i].c=i;
		int size=0; int size1=0; int k=1;
		priority_queue<com>Q;
		priority_queue<com,vector<com>,greater<com> > Q1;
		//Q记录大根堆,即最不优的那份订单,Q1记录之前的订单中和之后订单不冲突为优先的堆,即以右区间为关键字的小根堆。
		for(int i=1;i<=n;i++){
			int j=i;
			while(a[j].a==a[i].a){
				Q.push(a[j]); size++;
				Q1.push(a[j]);
				h[j]=1; j++;
			}
			for(com p=Q1.top();p.b<a[i].a;Q1.pop(),p=Q1.top()){
				if(h[p.c]) size1++;//计算有多少个和之后的没有冲突的订单,用size1记录,size记录有多少分订单目前打算要做。
			}
			i=j-1;
			while(size-size1>m){
				com jk=Q.top();
				h[jk.c]=0;
				Q.pop(); size--;
			}
		}
		printf("%d\n",size);
	}
} 



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值