【BZOJ】3389: [Usaco2004 Dec]Cleaning Shifts安排值班

Description

    一天有T(1≤T≤10^6)個時段.約翰正打算安排他的N(1≤N≤25000)只奶牛來值班,打掃
打掃牛棚衛生.每隻奶牛都有自己的空閒時間段[Si,Ei](1≤Si≤Ei≤T),只能把空閒的奶牛安排出來值班.而且,每個時間段必需有奶牛在值班.  那麼,最少需要動用多少奶牛參與值班呢?如果沒有辦法安排出合理的方案,就輸出-1.

Input

 
    第1行:N,T.
    第2到N+1行:Si,Ei.

Output

 
    最少安排的奶牛數.

Sample Input


3 10
1 7
3 6
6 10

Sample Output


2


樣例說明
奶牛1和奶牛3參與值班即可.


  題解:

  圖論跑最短路什麼的解法我顯然不會。。

  所以直接貪心,或者類似一個dp的東西

  先按左端點之後按照右端點拍一下序

  可以記錄下對當前的位置,至少需要多少個區間才能覆蓋掉

  那麼考慮所有在這個區間以內的子區間,用這些子區間來更新大區間的答案。

  排完序之後查找會非常方便。

  還有就是+1 -1什麼的弄了好長時間……

  (順便代碼熟悉一下VS2013,空格好多啊)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
const int MAXN = 1e6 + 1;
struct xx
{
	int l, r;
}a[25001];
inline bool cmp(xx a, xx b)
{
	if (a.l == b.l) return a.r < b.r;
	return a.l < b.l;
}
int main()
{
	int n, T,i,j;
	scanf("%d%d", &n, &T);
	for (i = 1; i <= n; i++)
	{
		scanf("%d%d", &a[i].l, &a[i].r);
	}
	sort(a + 1, a + n + 1, cmp);
	int now = 0, cnt=0, temp;
	int ans = 0;
	while (now < T)
	{
		temp = now;
		while (cnt < n&&a[cnt+1].l <= temp + 1)
		{
			cnt++;
			now = max(now, a[cnt].r);
		}
		if ((cnt == n&&a[cnt].r<T) || (a[cnt+1].l>now + 1))
		{
			puts("-1");
			return 0;
		}
		ans++;
	}
	if (now < T)
	{
		puts("-1");
		return 0;
	}
	printf("%d\n", ans);
}


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