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;
}
凡所不能将我击倒的,都将使我更加强大
原文地址:https://www.cnblogs.com/StarRoadTang/p/13264491.html