天天看點

【POJ - 2376】Cleaning Shifts

【POJ - 2376】Cleaning Shifts

Cleaning Shifts

Descriptions:

原文是English,我這就直接上Chinese了,想看原文的點一下連結哦

大表哥配置設定 N (1 <= N <= 25,000) 隻中的一些奶牛在牛棚附近做些清潔。 他總是要讓至少一隻牛做清潔。他把一天分成T段(1 <= T <= 1,000,000), 第一段是1,最後一段是T 

每隻奶牛隻在一些時間段有空。奶牛如果選擇某一段時間,則必須完成整段時間的工作 

你的任務是幫助FJ安排一些奶牛,使每段時間至少有一隻奶牛被安排來做這件事。并且奶牛數應盡可能小。如果不可能辦到,輸出-1

Input

注意,輸入包含多組測試資料,請處理到檔案結束

* 第一行:N和T 

* 第二行至N+1行: 每一行包括奶牛能工作的開始和結束時間。閉區間。

Output

*每組資料一行,輸出完成清潔所需最少的奶牛數,如果不可能辦到,輸出-1

Sample Input

3 10
1 7
3 6
6 10      

Sample Output

2      

題目連結:

https://vjudge.net/problem/POJ-2376

給定N個小區間以及區間起點終點,求能用它們覆寫區間[1,T]的最小組合。

貪心政策是從左往右,盡量選擇長度最大的區間。

首先對所有奶牛排序,按照開始時間排序。

然後更新起點=終點+1,搜尋剩下的奶牛中能夠覆寫這個起點同時終點最遠的那一頭,更新終點。

AC代碼;

#include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#define mod 1000000007
#define eps 1e-6
#define ll long long
#define INF 0x3f3f3f3f
#define ME0(x) memset(x,0,sizeof(x))
using namespace std;
int N,T;
struct cow
{
    int s;//開始時間start的縮寫
    int e;//結束時間end的縮寫
    int no;
    bool operator<(const cow &c)const//按開始時間從大到小排序
    {
        return s<c.s;
    }
};

int main()
{
    while(cin>>N>>T)
    {
        cow cows[25010];//在這裡設定數組就不用每次都重置數組了
        for(int i=0; i<N; ++i)
            cin>>cows[i].s>>cows[i].e;
        sort(cows,cows+N);//排序
//        for(int i=0; i<N; i++)
//            cout<<cows[i].s<<" "<<cows[i].e<<endl;
        int over=0;//結束時間
        int pos=0;//位置
        int sum=0;//一共幾頭牛
        while(over<T)
        {
            int start=over+1;//每次的開始時間都是上一次的結束時間+1
//            cout<<"***"<<start<<endl;
            for(int i=pos; i<N; ++i)
            {
                if(cows[i].s<=start)//能夠覆寫起始點 
                {
                    if(cows[i].e>over)
                        over=max(over,cows[i].e);//将結束時間延長到最遠
                }
                else
                {
                    //不能覆寫起點,說明上一頭牛的終點就是最遠點,需要換一頭牛了
//                  cout<<cows[i].s<<" "<<cows[i].e<<endl;
                    pos=i;
                    break;
                }
            }
            // 沒找到這樣的牛,失敗 
            if(start>over)
            {
                cout<<-1<<endl;
                break;
            }
            //找到了,+1
            else
                ++sum;
        }
        if(over>=T)//正常跳出循環,輸出sum即可
            cout<<sum<<endl;
    }
}      

posted on 2019-06-17 21:37 Sky丨Star 閱讀(...) 評論(...) 編輯 收藏