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