1. 程式人生 > 其它 >CSP-S 2021 T1 廊橋分配

CSP-S 2021 T1 廊橋分配

仔細分析一下這道題目,我們會發現當我們飛機依次進入的時候廊橋編號可以隨便選擇,沒有要求。
那我們預設按照順序來,這樣可以方便許多。於是,我們就可以使用——優先佇列!(不知道寫啥,看註釋)

#include<bits/stdc++.h>
using namespace std;
int m[2],n;
struct plane{//飛機的結構體
	int l,r;//左端點右端點
}a[2][100005];//a即輸入的
int ans[2][100005];//表示字首和,ans[i][j]表示給第i區(0為國內)j個機位最多可以停多少飛機。
bool mp(plane a,plane b){//排序用
	return a.l<b.l;
}
void js(int bh){//計算,bh表示當前計算第幾區
	priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > smwy;//smwy存停著的飛機的離開時間和停靠位置
	priority_queue<int,vector<int>,greater<int> > ytemp;//ytemp是random_shuffle("empty"),存空閒位置
	for(int i=1;i<=n;i++) ytemp.push(i);//全是空閒
	for(int i=1;i<=m[bh];i++){//先到先得
		while(!smwy.empty()&&a[bh][i].l>=smwy.top().first){//只要還有飛機而且已經過了離開時間
			ytemp.push(smwy.top().second);smwy.pop();//離開,增加空位
		}
		if(ytemp.empty()) continue;//沒有空位了
		int tmp=ytemp.top();//最小的
		ans[bh][tmp]++;smwy.push(make_pair(a[bh][i].r,tmp));ytemp.pop();//tmp這個位置需要一個
		//push把飛機加入停著的優先佇列裡
		//pop就是說明這個地方沒有空位了
	}
	for(int i=1;i<=n;i++) ans[bh][i]+=ans[bh][i-1];//字首和就可以算出從1~tmp總共可以停多少飛機
}
int main(){
	cin>>n>>m[0]>>m[1];
	for(int i=1;i<=m[0];i++) cin>>a[0][i].l>>a[0][i].r;
	for(int i=1;i<=m[1];i++) cin>>a[1][i].l>>a[1][i].r;
	sort(&a[0][0],&a[0][m[0]+1],mp);//排序
	sort(&a[1][0],&a[1][m[1]+1],mp);
	js(0);js(1);//都計算一遍
	int mx=-1;
	for(int i=0;i<=n;i++) mx=max(mx,ans[0][i]+ans[1][n-i]);//對於每種方式計算一遍
	cout<<mx<<endl;//輸出
	return 0;
}