Solution P7914 [CSP-S2021] 廊桥分配

题意

给你 \(n\) 个廊桥,有两个区的飞机,飞机先到先得,问如何分配使得能够停靠廊桥的飞机数量的最大,输出能够停靠廊桥的飞机数量的最大值。

Solution

让我们先忽略廊桥数量的限制来安排航班。我们维护一个空闲的廊桥队列,每到达一架航班,就给它安排编号最小的廊桥供其使用。

就是只要有飞机进来,如果没有空余的廊桥就直接加一个,即不考虑廊桥数量,然后分别记录每个廊桥所能停靠的最大飞机数,然后做一个前缀和,用 \(f_i\) 表示有 \(i\) 个廊桥时所能停靠的飞机数,最后枚举分配给国内区和国际区的廊桥数,即 \(ans = \max(f_i,f_{n-i})\) .

Code

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

const int N = 1e5 + 5;
int n, m1, m2, f[3][N], T[N], ans;
struct node
{
	int a, b;
}pl[3][N];

bool cmp(node x, node y)
{
	return x.a < y.a;
}

void work(int m, int k)
{
	sort(pl[k] + 1, pl[k] + m + 1, cmp);
	memset(T, 0, sizeof(T));
	for(int i = 1; i <= m; i++)
	{
		int t = 1;
		while(t <= n)
			if(pl[k][i].a > T[t]) 
			{
				T[t] = pl[k][i].b;
				f[k][t]++;
				break;
			}
			else t++;
	}
}

int main()
{
	scanf("%d%d%d", &n, &m1, &m2);
	for(int i = 1; i <= m1; i++)
		scanf("%d%d", &pl[1][i].a, &pl[1][i].b);
	for(int i = 1; i <= m2; i++)
		scanf("%d%d", &pl[2][i].a, &pl[2][i].b);
	work(m1, 1);
	work(m2, 2);
	for(int i = 1; i < n; i++)
		for(int j = 1; j < 3; j++)
			f[j][i + 1] += f[j][i];
	for(int i = 0; i <= n; i++)
	{
		int sum = f[1][i] + f[2][n - i];
		ans = max(ans, sum);
	}
	printf("%d", ans); 
	return 0;
}
posted @ 2022-10-08 15:16  xlqs23  阅读(42)  评论(0编辑  收藏  举报