CSP-S2021试题T1廊桥分配详讲

本文详细讲解了CSP-S2021试题T1廊桥分配问题,通过贪心算法和前缀和解决如何最大化停靠飞机数。首先阐述了使飞机能停靠廊桥的条件,然后利用优先队列模拟飞机进出过程,通过比较飞机到达和离开时间进行处理。最后,通过统计前缀和确定最优廊桥分配方案,实现时间复杂度为O(nlog2n)。
摘要由CSDN通过智能技术生成

来迟了来迟了,忘写了。
我们来看看这道卡了本蒟蒻3个小时的题。
传送门luoguP7913廊桥分配
题目大意:分为了国内和国外两部分,飞机来了要么停廊桥要么走,有空位一定停,且停最小的,要如何分配廊桥才能使停的飞机数最大。
首先我们要知道一个事实:

对于n架飞机,有无数个廊桥,其中的一架飞机k,能够停在廊桥的要求是总的廊桥数大于等于从第一架来的飞机到它飞来时使它能停到廊桥的廊桥数。
换而言之,对于某一架飞机,使它能停靠的廊桥数与有多少个廊桥无关。
至于为什么,我们可以思考:
尽管有无数个廊桥,但是飞机是严格按照停靠在最小的廊桥上,只要能满足前k架飞机能全部停廊桥数,那么其余的廊桥是没有用上的。

得到这个事实我们可以得到:
可以就用给出的总廊桥数来模拟,对于每一个廊桥,可以统计出在这个廊桥有多少个飞机停,所以总飞机停靠个数就是1~k个廊桥上的飞机总和,这个只需要前缀和处理即可,最后枚举分配给国内,国外的廊桥数,并加到一起,更新max即可。
我们应该如何模拟飞机离开和进入呢?
这里使用两个优先队列来分别维护最小编号的廊桥和所在哪个廊桥的飞机离开时间。
首先先按飞机来的时间进行排序,将编号最小的廊桥给它,删除该廊桥,再将它的离开时间和该廊桥编号压入另一小根堆中,并以离开时间为第一关键字来排序。
对于每一架来的飞机,比较它来的时间和堆中飞机离开时间,若离开时间小于了来的时间,那么就说明该飞机已经离开,删除该飞机,并又将它所在的廊桥编号压入堆中,循环直达堆顶飞机的离开时间大于了它来的时间。
然后就又重复操作,取出最小编号的廊桥,删除,将该廊桥和它离开时间一同压入堆中即可。
处理完后,我们得到每一廊桥停靠的飞机数量,那么统计前缀和即是有这么多个廊桥能停靠的飞机总数量。枚举比较即可。
时间复杂度O(nlog2n)
代码实现:

#include<bits/stdc++.h>
using namespace std;

const int N=1e5+5;
int n,m1,m2;
priority_queue<int>id;//最小廊桥编号 
priority_queue<pair<int,int> >q;//飞机离开时间和它所在的廊桥编号 
int cfa[N],cfb[N];//统计该廊桥有多少个飞机停 
struct node
{
   
	int l,r;
}a[N];

bool comp(node x,node y)
{
   
	return x.l<y.l;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值