#[USACO 2017 Jan S]Cow Dance Show#题解

题意

K头牛上台表演,最早表演完的牛下场按照表演顺序让接下来的牛表演,让你确定最小可同时上台表演的牛的数量K,使得他们表演的总时长不超过T。

做法:二分答案+优先队列

首先,确定二分答案,我们可以对表演的牛的数量二分,因为要求我们确定最小的可能数量,因此可写出以下代码:

    while(l<r)
    {
        int mid=(l+r)/2;
        if(check(mid))r=mid;
        else l=mid+1;
    }
    
    cout<<r<<endl;

接下来是关键的check函数呢,我们思考一下,根据题意,表演完了的要下场让牛按照表演的顺序依次上场,因此我们需要记录一下最早表演完的牛时间d[i]加上接下来要上场的牛的时间p.top()是否会超过我们的总时长,不合法直接返回,合法就利用优先队列更新一边即可,即:

bool check(int mid)
{
    priority_queue<int,vector<int>,greater<int>>p;
    
    //这里先预处理一边前mid头牛的最小时间
    for(int i=1;i<=mid;i++)p.push(d[i]);//d[i]表示每头牛表演时间
    
    for(int i=mid+1;i<=n;i++)
    {
        //当超过规定时间m返回
        if(d[i]+p.top()>m)return false;
        else
        {
            //合法就更新最小的表演时间
            int val=p.top();
            p.pop();
            p.push(val+d[i]);
        }
    }
    
    return true;
}