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

CSP2021-S T1 廊橋分配

這其實是一道貪心的題目,然而官方資料很水導致n^2也能卡過
題目廊橋分配
答案要的是分配出的停放飛機的最大值,但是我們並不知道哪一種方法最優,所以我們可以把國內機場和國際機場分配x個廊橋時的最大停放飛機求出來,然後從分配機場數0到n列舉一遍求出最大值。
至於求解廊橋裡的飛機停放數目,則可以建一個優先佇列和一個廊橋陣列來求解。
而優化程式碼則是建立兩個優先佇列,一個是為了存放能進入的廊橋的標號,一個是為了存放最後離開的時間,與一直到達時間作為比較。

點選檢視程式碼
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<queue>
using namespace std;

#define MA 100005

int n,m1,m2;
int pm1[MA]={0},tt1=0;
int pm2[MA]={0},tt2=0;
int en1[MA]={0},en2[MA]={0};
int as1[MA]={0},as2[MA]={0};
struct node1 {
	int fr,to;
	bool operator < (const node1 x)const {
		return fr>x.fr;
	}
};
struct node2 {
	int to,num;
	bool operator < (const node2 x)const {
		return to>x.to;
	}
};
priority_queue<node1>s1;
priority_queue<node2>s2;
bool cmp(int x,int y) {
	return x>y;
}
void rd1(int m,int &tot) {
	int i;
	int fr,to;
	
	while(!s1.empty())
		s1.pop();
//	while(!s2.empty())
//		s2.pop();
	
	for(i=1;i<=m;++i) {
		scanf("%d%d",&fr,&to);
		s1.push((node1){fr,to});
	}
	node1 x;
	//node2 y;
	//int num;
	bool flag;
	while(!s1.empty()) {
		x=s1.top();
		s1.pop();
		//printf("[%d,%d]\n",x.fr,x.to);
		//flag=0;
		for(i=1;i<=tot;++i)
			if(x.fr>=en1[i]) {
				en1[i]=x.to;
				++pm1[i];
				//flag=1;
				break;
			}
		if(i>tot) {
			++tot;
			++pm1[tot];
			en1[tot]=x.to;
		}
		//printf("%d %d]\n",i,tot);
	}
	//sort(pm1+1,pm1+1+m,cmp);
	for(i=1;i<=tt1;++i) {
		as1[i]=as1[i-1]+pm1[i];
	}
	return;
}
void rd2(int m,int &tot) {
	int i;
	int fr,to;
	
	while(!s1.empty())
		s1.pop();
//	while(!s2.empty())
//		s2.pop();
	
	for(i=1;i<=m;++i) {
		scanf("%d%d",&fr,&to);
		s1.push((node1){fr,to});
	}
	node1 x;
	//node2 y;
	//int num;
	bool flag;
	while(!s1.empty()) {
		x=s1.top();
		s1.pop();
		//printf("<>%d %d\n",x.fr,x.to);
		//flag=0;
		for(i=1;i<=tot;++i)
			if(x.fr>=en2[i]) {
				en2[i]=x.to;
				++pm2[i];
				//flag=1;
				break;
			}
		if(i>tot) {
			++tot;
			++pm2[tot];
			en2[tot]=x.to;
		}
	}
	//sort(pm2+1,pm2+1+m,cmp);
	for(i=1;i<=tt2;++i) {
		as2[i]=as2[i-1]+pm2[i];
	}
	return;
}
void print() {
	int i;
	puts("");
	for(i=1;i<=tt1;++i) {
		printf("%d ",pm1[i]);
	}
	puts("");
	puts("");
}
int main() {
	//freopen("airport.in","r",stdin);
	//freopen("airport.out","w",stdout);
	//int n,m1,m2;
	scanf("%d%d%d",&n,&m1,&m2);
	
	rd1(m1,tt1);
	rd2(m2,tt2);
	
	int ans=0,i;
	for(i=tt1+1;i<=n;++i) {
		as1[i]=as1[tt1];
	}
	for(i=tt2+1;i<=n;++i) {
		as2[i]=as2[tt2];
	}
	
	
	//print();
	
	
	for(i=0;i<=n;++i) {
		ans=max(as1[i]+as2[n-i],ans);
		//printf("%d\n",ans);
		//printf("[%d,%d]\n",as1[i],as2[i]);
	}
	printf("%d\n",ans);
	return 0;
}
優化程式碼
點選檢視程式碼
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<queue>
using namespace std;

#define MA 100005

int n,m1,m2;
int pm1[MA]={0},tt1=0;
int pm2[MA]={0},tt2=0;
int en1[MA]={0},en2[MA]={0};
int as1[MA]={0},as2[MA]={0}; 
struct node1 {
	int to,fr;
};
struct node2 {
	int to,num;
	bool operator < (const node2 x)const {
		return to>x.to;
	}
};
priority_queue<node2>s1;
priority_queue< int,vector<int>,greater<int> >s2;
bool cmp(int x,int y) {
	return x>y;
}
bool cmp2 (node1 x,node1 y) {
	return x.fr<y.fr;
}
node1 y[MA];
void rd(int m,int &tot,int *as) {
	int i;
	int fr,to;
	
	while(!s1.empty())
		s1.pop();
	while(!s2.empty())
		s2.pop();
	
	for(i=1;i<=m;++i) {
		scanf("%d%d",&y[i].fr,&y[i].to);
		s2.push(i);
	}
	sort(y+1,y+1+m,cmp2);
	int sz=0;
	for(i=1;i<=m;++i) {
		if(sz) {
			while(sz && y[i].fr>s1.top().to) {
				--sz;
				s2.push(s1.top().num);
				s1.pop();
			}
		}
		if(!s2.empty()) {
			tot=max(tot,s2.top());
			++as[s2.top()];
			s1.push((node2){y[i].to,s2.top()});
			s2.pop();
			++sz;
		}
	}
	for(i=1;i<=tot;++i) {
		as[i]=as[i-1]+as[i];
	}
	return;
}
void print() {
	int i;
	puts("");
	for(i=1;i<=tt1;++i) {
		printf("%d ",pm1[i]);
	}
	puts("");
	puts("");
}
int main() {
	//freopen("airport.in","r",stdin);
	//freopen("airport.out","w",stdout);
	scanf("%d%d%d",&n,&m1,&m2);
	
	rd(m1,tt1,as1);
	rd(m2,tt2,as2);
	
	int ans=0,i;
	for(i=tt1+1;i<=n;++i) {
		as1[i]=as1[tt1];
	}
	for(i=tt2+1;i<=n;++i) {
		as2[i]=as2[tt2];
	}

	//print();
	
	for(i=0;i<=n;++i) {
		ans=max(as1[i]+as2[n-i],ans);
	}
	printf("%d\n",ans);
	return 0;
}