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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/BeyondW__/article/details/52513997

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);
}


阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页