UVA 1450

来源:互联网 发布:java base64工具类 编辑:程序博客网 时间:2024/05/29 07:26

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 Wor E 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     WEtimes     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 B2receive 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 casesT is 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 time i, 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 13 3 20 32 06 0 11 11 21 11 16 0

Sample Output 

0 3 5
这道题一开始不会 , 后来学习了某大神的解题报告才写出 , 总的思路是二分结果 , 先把起飞的机会留着,当suma > k + 1||sumb > k + 1时再去回头算起飞!
#include <cstdio>#include <cmath>#include <algorithm>#include <iostream>#include <cstring>#include <map>#include <string>#include <stack>#include <cctype>#include <vector>#include <queue>#include <set>using namespace std;const int MAXN = 5010 + 50;const int maxw = 100 + 20;const long long LLMAX = 0x7fffffffffffffffLL;const long long LLMIN = 0x8000000000000000LL;const int INF = 0x7fffffff;const int IMIN = 0x80000000;#define eps 1e10-8#define mod 1000000007typedef long long LL;const double PI = acos(-1.0);typedef double D;//#define Online_Judge#define outstars cout << "***********************" << endl;#define clr(a,b) memset(a,b,sizeof(a))#define FOR(i , x , n) for(int i = (x) ; i < (n) ; i++)#define FORR(i , x , n) for(int i = (x) ; i <= (n) ; i++)#define REP(i , x , n) for(int i = (x) ; i > (n) ; i--)#define REPP(i ,x , n) for(int i = (x) ; i >= (n) ; i--)int a[MAXN] , b[MAXN] , n;bool check(int k){    int suma = 0 , sumb = 0 ,  cnta = 0 , cntb = 0 , cnt = 0;    FOR(i ,0 , n)    {        suma += a[i];        sumb += b[i];        if(a[i] > k + 1||b[i] > k + 1)return false;        while(suma > k + 1)        {            if(cnt == 0||cnta == 0)return false;            cnta--;            cnt--;            suma--;        }        while(sumb > k + 1)        {            if(cnt == 0||cntb == 0)return false;            cntb--;            cnt--;            sumb--;        }        if(cnta < suma)cnta++;///飞机能从a起飞的次数        if(cntb < sumb)cntb++;///飞机能从b起飞的次数        if(cnt < suma + sumb)cnt++;///飞机总共能起飞的次数    }    return true;}int main(){    ios::sync_with_stdio(false);    #ifdef Online_Judge        freopen("in.txt","r",stdin);        freopen("out.txt","w",stdout);    #endif // Online_Judge    int  T;    scanf("%d",&T);    while(T--)    {        scanf("%d",&n);        int suma = 0 , sumb = 0;        FOR(i , 0 , n)        {            scanf("%d%d",&a[i] , &b[i]);            suma += a[i];            sumb += b[i];        }        int l = 0 , r = max(suma , sumb), ans =0;        while(l < r)        {            int mid = l + ((r - l) >> 1);            if(check(mid))            {                ans = mid;                r = mid;            }            else l = mid + 1;        }        printf("%d\n",ans);    }    return 0;}