• UVA 1335 Beijing Guards


    Input
    The input contains several blocks of test eases. Each case begins with a line containing a single integer
    l ≤ n ≤ 100000, the number of guard towers. The next n lines correspond to the n guards: each line
    contains an integer, the number of awards the guard requires. Each guard requires at least 1, and at
    most l00000 awards. Guard i and i + 1 are neighbors, they cannot receive the same award. The rst
    guard and the last guard are also neighbors.
    The input is terminated by a block with n = 0.
    Output
    For each test case, you have to output a line containing a single integer, the minimum number x of
    award types that allows us to motivate the guards. That is, if we have x types of awards, then we can
    give as many awards to each guard as he requires, and we can do it in such a way that the same type
    of award is not given to neighboring guards. A guard can receive only one award from each type.
    Sample Input
    3
    4
    2
    2
    5
    2
    2
    2
    2
    2
    5
    1
    1
    1
    1
    1
    0
    Sample Output
    8
    5
    3

    分奇偶两种情况,奇要二分,思考相应的策略,画图思考

    #include <cstdio>
    #include <algorithm>
    
    using namespace std;
    
    int A[100000 + 10], n, p;
    
    bool ok(int p) {
        int x = A[0], y = p - x, l1 = x, r1 = y;
        for (int i = 1, l, r; i < n; ++i, l1 = l, r1 = r) {
            if (i & 1) {
                l = min(x - l1, A[i]); //放左边
                r = A[i] - l;
            } else {
                r = min(y - r1, A[i]); //放右边
                l = A[i] - r;
            }
        }
    
        return !l1;  //左边不应有值
    }
    
    
    int main() {
        while (scanf("%d", &n) && n) {
            for (int i = 0; i < n; ++i) {
                scanf("%d", &A[i]);
            }
            if (p = A[0], n == 1) goto la;
            A[n] = A[0];
            for (int i = 1; i <= n; ++i) {
                p = max(A[i] + A[i - 1], p);
            }
    
            if (n & 1) {
                int l = p, r = 0;
                for (int i = 0; i < n; ++i) {
                    r = max(r, 3 * A[i]);
                }
                while (l < r) {
                    int m = (l + r) >> 1;
                    if (ok(m))
                        r = m;
                    else
                        l = m + 1;
                }
                p = r;
            }
            la:
            printf("%d
    ", p);
        }
    }
  • 相关阅读:
    特殊集合
    推箱子
    集合
    数组

    循环语句 练习题
    穷举与迭代
    循环语句
    练习题
    switch case
  • 原文地址:https://www.cnblogs.com/wangsong/p/7624618.html
Copyright © 2020-2023  润新知