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

来源:互联网 发布:广州淘宝二手汽车网 编辑:程序博客网 时间:2024/06/05 08:40

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


0 0
原创粉丝点击