• Codeforces 1373F Network Coverage


    昨晚梦到自己把这道题的题解写了 , 既然梦到了 , 那就写吧

    题目链接

    https://codeforces.com/problemset/problem/1373/F

    题目大意

    有 N 个城市 , 这 N 个城市围成一个圈 ( N + 1 = 1 )

    其中第 i 个城市需要 ai 台设备 , 而第 i 个城市本身含有 bi 台设备

    现在告诉你第 i 个城市的设备可以提供给它自己或第 i + 1 个城市

    问是否能通过合理的分配使得每个城市的设备都满足需求

    解题思路

    第 i 个城市最后的设备数 = 第 i 个城市提供给自身的设备数 + 第 i - 1个城市提供给它的设备数

    当一个城市的提供给自身的设备数确定之后 , 剩下的城市就可以通过贪心来分配

    那么暴力的做法就是枚举第一个城市分配给自身的设备数 K1 , 然后判断是否可行

    而通过观察我们会发现 , K1 越大 , 第 2 ~ n 个城市可能被分配的个数就会减少

    K1 越小 , 第 n 个城市给第一个城市分配的设备数加上 K1 就可能小于 a1

    于是我们可以对 K1 二分 , 当第 2 ~ n 个城市不够分配时 , 我们让 R = mid - 1

    当第 n 个城市给第一个城市分配的设备数 + K1 < ai 时 , 我们让  L = mid + 1

    当两者都合法时 , 我们直接结束二分输出答案即可 , 复杂度 NlogN

    AC_Code

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 1e6 + 10;
    int a[N] , b[N] , n , t;
    int check(int mid)
    {
        int pre = b[1] - mid;
        for(int i = 2 ; i <= n ; i ++)
        {
            pre = min(b[i] + pre - a[i] , b[i]);
            if(pre < 0) return -1;
        }
        if(pre + mid >= a[1]) return 1;
        else return 0; 
    }
    signed main()
    {
        ios::sync_with_stdio(false) , cin.tie(0);
        cin >> t;
        while(t --)
        {
            cin >> n;
            for(int i = 1 ; i <= n ; i ++) cin >> a[i];
            for(int i = 1 ; i <= n ; i ++) cin >> b[i];
            int l = 0 , r = b[1] , mid , flag = 0;
            while(l <= r)
            {
                int mid = l + r >> 1;
                if(check(mid) == -1) r = mid - 1;
                else if(!check(mid)) l = mid + 1;    
                else { flag = 1 ; break ; }
            } 
            if(!flag) cout << "NO
    ";
            else cout << "YES
    ";
        }
        return 0;
    }
    凡所不能将我击倒的,都将使我更加强大
  • 相关阅读:
    p1373【奶牛的卧室】
    p1248【交错匹配】(DP)
    QBXT模拟赛T3
    NOIP冲刺班的考试总结
    欧拉回路的一些东西
    一道dp题目
    Blocks
    玩具取名
    Y的积木
    游荡的奶牛
  • 原文地址:https://www.cnblogs.com/StarRoadTang/p/13264491.html
Copyright © 2020-2023  润新知