POJ 2376 Cleaning Shifts 区间贪心

来源:互联网 发布:java创建日志文件 编辑:程序博客网 时间:2024/05/17 05:50

很简单的贪心,按照区间的开始位置从小到大,如果开始位置相同,就按照结束位置从小到大排序。

然后不断的延伸区间,假如当前区间是[1,5] 接下来我们开始寻找有哪些区间的开始位置小于5呢?结果我们发现有2个区间[2,6],[3,7],然后我们选择结束位置靠后的那个,也就是[3,7],所以现在的区间就被我们延伸成了[1,7]。以此类推,看最后能不能延伸到[1,T]

注意三个点

1.排序结束后,第一个区间的开始位置一定是1

2.[1,3]和[4,5]认为是连续的区间段

3.假如现在区间是[1,7],我们继续寻找到[5,6],[4,6]但是发现这两个区间的结束位置都不能使得区间延伸。也就是寻找到的区间不一定都是可以更新的。

#include "set"#include "map"#include "queue"#include "stack"#include "cmath"#include "cstdio"#include "cstdlib"#include "iostream"#include "algorithm"#define EPS 1e-10#define MAX_N 30000#define Pi acos(-1.0)#define INF 0x3f3f3f3fusing namespace std;struct data{    int s, t;    bool operator < (const data & b) const    {        return s < b.s || (s == b.s && t < b.t);    }};data cow[MAX_N];int N, T;int solve(){    sort(cow, cow + N);    int res = 0, q = 0, last = 0;//last表示当前区间的结束位置,res表示已经使用的区间个数,q是下标    if (cow[0].s != 1) return -1;    while (q < N)    {        int p = q;        while (q < N && cow[q].s <= last + 1)            q++;        if (q == p) break;//说明我们已经寻找不到有更新可能的区间了        int m = -1, j;        for (int i = p; i < q; i++)        {            if (m < cow[i].t && cow[i].t > last)            {                m = cow[j = i].t;            }        }        if (m == -1) break;//说明我们寻找到的区间都更新不了当前区间        res++;        last = m;    }    if (last == T)        return res;    return -1;}int main (){    //freopen ("in.txt", "r", stdin);    //freopen ("out.txt", "w", stdout);    while (~scanf("%d%d", &N, &T))    {        for (int i = 0; i < N; i++)        {            scanf("%d%d", &cow[i].s, &cow[i].t);        }        printf("%d\n", solve());    }    return 0;}


0 0
原创粉丝点击