Codeforces 1373 F. Network Coverage —— 想法,貪心

This way

題意:

現在有n個城市圍成一個環,每個城市有ai個家庭需要供電,並且每個城市有一個發電廠,可以供給第i和第i+1個城市共bi個家庭的電。問你每個家庭是否都能得到電。

題解:

那麼我們首先選擇一個i,要求是bi>=ai。
那麼我們假設bi首先滿足ai,然後多的供給給下一個城市,這樣做一遍,很明顯中間會有不夠的地方,此時我們就需要讓選擇的這個起始城市多供給給缺的部分。
那麼假設所有缺的加起來爲mx,如果mx>ai的話,bi就算將bi全部都傳遞過去也不夠,所以這種情況不行。
如果mx<=ai,那麼就表示有戲,我們就讓bi少傳遞mx給ai,將mx的電傳遞到下一個。那麼此時bi傳遞給ai的電就是ai-mx,於是ai就還需要mx格電,此時我們設傳遞的電的數量爲bi-ai+mx,將ai置爲mx,bi置爲0.
然後再做一遍,如果不行就是真的不行,中間一定有斷點使得bi的電傳不過去。
時間複雜度應該是O(n)O(n)的,但是可能常數太大導致花了700ms左右,時間複雜度應該可以優化,但沒必要。

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e6+5;
ll a[N],b[N];
int n;
int main()
{
    int t;
    scanf("%d",&t);
    for(int tim=1;tim<=t;tim++){
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%lld",&a[i]);
        int sta=-1;
        for(int i=0;i<n;i++)
            scanf("%lld",&b[i]),sta=b[i]>=a[i]?i:sta;
        if(sta==-1){
            printf("NO\n");
            continue;
        }
        ll res=0,mx=0;
        for(int i=sta;i<=sta+n-1;i++){
            int u=i%n;
            if(b[u]+res>=a[u])
                res=min(b[u],res+b[u]-a[u]);
            else
                mx+=a[u]-b[u]-res,res=0;
        }
        if(mx){
            if(mx>a[sta]){
                printf("NO\n");
                continue;
            }
            res=b[sta]-a[sta]+mx;
            a[sta]=mx;
            b[sta]=0;
            mx=0;
            for(int i=sta+1;i<=sta+n;i++){
                int u=i%n;
                if(b[u]+res>=a[u])
                    res=min(b[u],res+b[u]-a[u]);
                else{
                    mx=1;
                    break;
                }
            }
            if(mx)
                printf("NO\n");
            else
                printf("YES\n");
        }
        else
            printf("YES\n");
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章