键盘敲碎夜深沉,代码如麻乱假真 • 3天前
/*
枚举国内和国际区的廊桥数量
有重复x->x+1加一个廊桥能多多少个飞机
当廊桥为x或x+1时,前x个廊桥已经是已经是最优的
故有空位时,优先安排最先的廊桥
*/
#include<bits/stdc++.h>
using namespace std;
int n,m1,m2;
struct pl{ //航班结构体
int st;
int en;
bool operator < (pl b2) const { //const表示该函数不会对变量造成影响
return st < b2.st; //按到达时间从小到大排序
}
}a[100005],b[100005];
int ac[100005],bc[100005]; //预处理出有i个廊桥时,第i个廊桥的飞机数量
struct Bridge{
int index; //廊桥编号
int endt; //上一个飞机的结束时间
bool operator < (Bridge b2) const { //const表示该函数不会对变量造成影响
return endt > b2.endt;
}
};
int aused,bused;
priority_queue<Bridge> aw; //已停飞机的廊桥(结束时间从大到小)
priority_queue<int ,vector<int>,greater<int>> ae; //空着的廊桥
//同理,国际
priority_queue<Bridge> bw; //已停飞机的廊桥
priority_queue<int ,vector<int>,greater<int>> be; //空着的廊桥
int main(){
cin>>n>>m1>>m2;
for(int i=1;i<=m1;i++) cin>>a[i].st>>a[i].en;
for(int i=1;i<=m2;i++) cin>>b[i].st>>b[i].en;
sort(a+1,a+m1+1);
sort(b+1,b+m2+1);
for(int i=1;i<=m1;i++){ //枚举飞机来
while(!aw.empty()&&aw.top().endt<a[i].st){ //来时有空的廊桥
ae.push(aw.top().index);
aw.pop();
}
if(ae.empty()){ //没有空廊桥
if(aused<n){
aused++; //直接建
ac[aused]++; //该廊桥新停了一架飞机
aw.push({aused,a[i].en}); //加入已停廊桥队列
}
//已用的大于n,不管它
}else{ //有空廊桥
int x=ae.top(); //选最小编号的空廊桥
ae.pop();
ac[x]++; //该廊桥多停了一架飞机
aw.push({x,a[i].en}); //加入已停飞机廊桥队列
}
}
//国际同理
for(int i=1;i<=m2;i++){ //枚举飞机来
while(!bw.empty()&&bw.top().endt<b[i].st){ //来时有空的廊桥
be.push(bw.top().index);
bw.pop();
}
if(be.empty()){ //没有空廊桥
if(bused<n){
bused++; //直接建
bc[bused]++; //该廊桥新停了一架飞机
bw.push({bused,b[i].en}); //加入已停廊桥队列
}
//已用的大于n,不管它
}else{ //有空廊桥
int x=be.top(); //选最小编号的空廊桥
be.pop();
bc[x]++; //该廊桥多停了一架飞机
bw.push({x,b[i].en}); //加入已停飞机廊桥队列
}
}
//前面求出的是具体某个廊桥的最优解
for(int i=1;i<=n;i++){
ac[i]+=ac[i-1];
bc[i]+=bc[i-1];
} //前缀和处理之后,就是安排i个廊桥的最优飞机数
int ans=-1;
for(int i=0;i<=n;i++) ans=max(ans,ac[i]+bc[n-i]); //枚举廊桥分配数
cout<<ans<<"\n";
return 0;
}
评论:
请先登录,才能进行评论