(advanced) UVA 二分+贪心 1450 - Airport

A big city has an international airport handling 40 million passengers a year. But this is notorious as one of the most congested airports in the world. In this airport, there is only one landing strip as in the above figure. Therefore the landing strip is always crowded with a lot of aircrafts waiting for a takeoff. There are two ways, say west-road W and east-road E, to approach the landing strip. The aircrafts are waiting for a takeoff on the two roads as in the above figure.

\epsfbox{p4725.eps}

At each time t, an arbitrary number of aircrafts arrive on the roads W and E. Each aircraft arriving on W orE at time t receives a rank, which is equal to the number of the waiting aircrafts on the same road to precede it. Then the one of W and E is chosen by a control tower, and the most front aircraft on the road leaves the ground. Given an information of the arriving aircrafts at times, we are concerned in the takeoff schedule of the control tower to minimize the maximum rank of the aircrafts.

  roads  
   WE
times    
 1 A1A2A3B1B2
 2  B3B4B5
 3 A4A5 

For example, the above table represents the aircrafts arriving on the roads W and E at each time. At time 1, the aircrafts A1A2 and A3 receive the ranks 0, 1 and 2, respectively, and the aircrafts B1 and B2 receive the ranks 0 and 1, respectively. Then the control tower allows the aircraft B1 on the road E to take off, and B1 leaves the ground. At time 2, the aircrafts B3B4, and B5 receive the ranks 1, 2 and 3, respectively. Then A1 on the road W is allowed to take off, and it leaves the ground. At time 3, the aircrafts A4 and A5 receive the ranks 2 and 3, respectively. So the maximum rank of the aircrafts is 3, and this is the minimum of the maximum rank over all the possible takeoff schedules.

Input 

Your program is to read from standard input. The input consists of T test cases. The number of test cases Tis given on the first line of the input. The first line of each test case contains an integer n (1$ \le$n$ \le$5000) , the number of times. In the next n lines of each test case, the i-th line contains two integer numbers ai and bi, representing the number of arriving aircrafts on the road W and E, respectively, at timei, where 0$ \le$aibi$ \le$20.

Output 

Your program is to write to standard output. Print exactly one line for each test case. The line contains the minimum of the maximum rank over all the possible takeoff schedules.

The following shows sample input and ouput for three test cases.

Sample Input 

3 
1 
1 1
3 
3 2
0 3
2 0
6 
0 1
1 1
1 2
1 1
1 1
6 0

Sample Output 

0 
3 
5


题意:飞机场有两个跑道,每个时间会有若干架飞机过来等待,每一次你能选择两个跑道中的一条让一架飞机起飞。问你最小的最大飞机等待数-1.


思路:我们可以二分答案,然后判断是否有解。但是我们怎样才能快速的判断是否有解呢?我们可不能直接去搜,这样的话,二分就没多大意义了。我们要把二分出的上界的条件用上。这里我们可以根据这个上界得出一个贪心的策略。如果一条跑道能更快超过上界。那么我们优先让这条跑道的飞机起飞。如果一样的话,我们优先让那个超的更多的跑道起飞。基本思路就是这样的。注意如果一条跑道没有飞机的话,你不能让任何飞机起飞,同时如果一开始就没有任何飞机进入的话,答案应该是0,不要输出-1了。


代码:

#include<iostream>
#include<cstdio>
#include<string.h>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int maxn = 5000;
int a[maxn], b[maxn];
int n;

void input()
{
	scanf("%d", &n);
	a[0] = b[0] = 0;
	for (int i = 1; i <= n; ++i)
	{
		scanf("%d%d", a + i, b + i);
		a[i] += a[i - 1];
		b[i] += b[i - 1];
	}
	a[n + 1] = a[n];
	b[n + 1] = b[n];
}

int Bin(int left, int right, int x, int *arr)
{
	while (left <= right)
	{
		int mid = (left + right) >> 1;
		if (arr[mid] > x) right = mid - 1;
		else left = mid + 1;
	}
	return left;
}

bool ok(int limit)
{
	int s1 = a[1], s2 = b[1];
	if (s1 > limit || s2 > limit) return false;
	for (int i = 2; i <= n; ++i)
	{
		int x = Bin(i, n, limit-s1+a[i-1], a);
		int y = Bin(i, n, limit-s2+b[i-1], b);
		if (x < y)
		{
			if (s1 == 0) --s2;
			else --s1;
			if (s2<0) s2 = 0;
		}
		else if (x>y)
		{
			if (s2 == 0) --s1;
			else --s2;
			if (s1 < 0) s1 = 0;
		}
		else
		{
			if (s2 == 0) --s1;
			else if (s1 == 0) --s2;
			else if (s1 + a[x] - a[i - 1]<s2 + b[y] - b[i - 1])
				--s2;
			else --s1;
			if (s1<0) s1 = 0;
			if (s2<0) s2 = 0;
		}
		s1 += a[i] - a[i - 1], s2 += b[i] - b[i - 1];
		if (s1 > limit || s2 > limit) return false;
	}
	return true;
}

void solve()
{
	int left = 0, right = 20 * n;
	int ret = 1e9;
	while (left <= right)
	{
		int mid = (left + right) >> 1;
		if (ok(mid))
		{
			right = mid - 1;
			if (ret > mid) ret = mid;
		}
		else left = mid + 1;
	}
	if (ret > 0)--ret;
	printf("%d\n", ret);
}

int main()
{
	int T; cin >> T;
	while (T--)
	{
		input();
		solve();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值