1. 程式人生 > >Cleaning Shifts-POJ-2376

Cleaning Shifts-POJ-2376

原題: Farmer John is assigning some of his N (1 <= N <= 25,000) cows to do some cleaning chores around the barn. He always wants to have one cow working on cleaning things up and has divided the day into T shifts (1 <= T <= 1,000,000), the first being shift 1 and the last being shift T.

Each cow is only available at some interval of times during the day for work on cleaning. Any cow that is selected for cleaning duty will work for the entirety of her interval.

Your job is to help Farmer John assign some cows to shifts so that (i) every shift has at least one cow assigned to it, and (ii) as few cows as possible are involved in cleaning. If it is not possible to assign a cow to each shift, print -1. Input

  • Line 1: Two space-separated integers: N and T

  • Lines 2…N+1: Each line contains the start and end times of the interval during which a cow can work. A cow starts work at the start time and finishes after the end time. Output

  • Line 1: The minimum number of cows Farmer John needs to hire or -1 if it is not possible to assign a cow to each shift. Sample Input 3 10 1 7 3 6 6 10 Sample Output 2 Hint This problem has huge input data,use scanf() instead of cin to read data to avoid time limit exceed.

INPUT DETAILS:

There are 3 cows and 10 shifts. Cow #1 can work shifts 1…7, cow #2 can work shifts 3…6, and cow #3 can work shifts 6…10.

OUTPUT DETAILS:

By selecting cows #1 and #3, all shifts are covered. There is no way to cover all the shifts using fewer than 2 cows. 題意: 有n頭奶牛,每一頭奶牛都有自己的工作時間,先將一天分成t個工作時段,問能否用最少的牛完成工作,某個時段可以有兩頭牛一起工作,若是不能完成輸出-1,能完成輸出所需最少牛數。 題解: 這道題目的貪心思想: 每一次都選起始時間再上一次結束時間之前的奶牛,並且找結束時間最大的那一頭奶牛,即可,若是中間有空缺,或者開始和結尾不能完成工作輸出-1; 更多細節見程式碼: 附上AC程式碼:

#include <iostream>
#include <algorithm>
using namespace std;
int n,t,vis;
struct node
{
    int st,ed;
}a[25005];
bool cmp(node a,node b)
{
    if(a.st==b.st)
        return a.ed>b.ed;//若是起始時間相同,則按照結束時間從大到小排序
    return a.st<b.st;//按照開始時間從小到大排序
}
int main()
{
    ios::sync_with_stdio(false);//減少cin消耗的時間
    while(cin>>n>>t)
    {
    for(int i=1;i<=n;i++)
    {
        cin>>a[i].st>>a[i].ed;
    }
    sort(a+1,a+n+1,cmp);//排序
    if(a[1].st>1)//如果最小的開始時間都大於1,則註定不能完成任務
    {
        cout<<"-1"<<endl;
        continue;
    }
    int start=a[1].ed,cnt=1,maxi;//由於當st相同時按照ed從大到小排序,所以第一個的結束時間一定最長,所以一定會用第一個
    for(int i=1;i<=n+1;i++)
    {
        if(a[i].st<=start+1&&a[i].ed>start)
        {
            maxi=i;//記錄ed最大的那一頭奶牛的下標
            while(a[i].st<=start+1&&i<=n)//在滿足條件的情況下,找出結束時間最長的那一頭
            {
                if(a[i].ed>a[maxi].ed)
                {
                    maxi=i;
                }
                i++;
            }
            start=a[maxi].ed;//更新開始時間
            i=maxi;//下一次的i從maxi+1開始
            cnt++;//所需牛數加一
            if(start>=t)//如果結束時間已經覆蓋了一整天可以直接推出迴圈,合理剪枝
                break;
        }
    }
    if(start<t)cout<<-1<<endl;//如果迴圈結束最後任然不能完成任務
    else cout <<cnt<< endl;
    }
    return 0;
}

歡迎評論!