UVA 1450 Airport(二分+想法题)

题意:

有一个飞机场,有两条待飞跑到w和e,一条起飞跑道,每一时刻只能起飞一架飞机,然后有w[i]和e[i]架飞机进入w和e跑道,飞机编号从0开始,问说如何安排起飞可以使得飞机编号的最大值最小。

解析:

由于是最大值最小化问题,所以要用到二分求解。二分枚举最大值 limit 判断该最大值是否满足题目所给的条件。
这题看来别人的代码理解了好久,感觉这题充满了技巧。
have 表示的是当前时刻先不发送飞机,预留下空间的数目,既然是预留下空间那么每个时刻都可以满足最优。
但是还有3种情况要考虑,
1. 如果当前的 sume=0sumw>0 表示当前e通道无法发送飞机,只能w通道发送飞机,sumw–。
2. 反之如果当前的 sumw=0sume>0 表示当前w通道无法发送飞机,只能e通道发送飞机,sume–。
3. 如果 sumw+sume>have ,如果两边的飞机数目大于预留的飞机数目表示当前还可以发送飞机,have++。

那么什么情况下是不满足题目条件的呢?
overe+overw>have ,表示当前的超出的飞机数目大于预留的空间,那么不符合条件。

AC代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
using namespace std;
typedef long long ll;
const int N = 5e3 + 10;
int w[N], e[N];
int n;
bool judge(int lim) {
    int sumw, sume, have;
    sumw = sume = have = 0;
    for(int i = 0; i < n; i++) {
        sumw += w[i], sume += e[i];
        int overw = max(sumw-lim, 0);
        int overe = max(sume-lim, 0);
        if(overw + overe > have) return false;
        if(sumw == 0 && sume > 0) sume--;
        else if(sume == 0 && sumw > 0) sumw--;
        else if(sumw && sume && sumw + sume > have) have++;
    }
    return true;
}
int main() {
    int T;
    scanf("%d", &T);
    while(T--) {
        scanf("%d", &n);
        int maxv = 0;
        for(int i = 0; i < n; i++) {
            scanf("%d%d", &w[i], &e[i]);
            maxv += max(w[i], e[i]);
        }
        int L = 1, R = maxv;
        while(L <= R) {
            int M = (L+R)/2;
            if(judge(M)) R = M-1;
            else L = M+1;
        }
        printf("%d\n", L-1);
    }
    return 0;
}

你可能感兴趣的:(uva,1450)