区间覆盖

Posted by 磊落 on May 11, 2020

区间覆盖

  • 将所有区间按照左端点从小到大排序

  • 从前往后依次枚举每个区间,在所有能覆盖start区间中,选择右端点最大的区间

  • 将Start更新成右端点最大值

  • 证明 ans 代表所有可行方案的最小值 cnt代表按照上述方案选法的某一个可行解 所以 ans <= cnt

  • 证明 ans >= cnt : 任何一个最优解都可以通过等价变换,变换成可行解,所以说明 ans >= cnt. 综上 ans == cnt

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;
int st, ed;
int n;
bool success = false;

struct Range
{
    int l, r;
    bool operator< (const Range& w)
    {
        return l < w.l;
    }
}range[N];

int main()
{
    scanf("%d%d", &st, &ed);
    scanf("%d", &n);

    for (int i = 0; i < n; i++)
    {
        scanf("%d%d", &range[i].l, &range[i].r);
    }
    
    sort(range, range + n);

    int res = 0;

    for (int i = 0; i < n; i++)
    {
        int j = i;
        int rd = -2e9;
        while (j < n && range[j].l <= st)
        {
            rd = max(rd, range[j].r);
            j ++;
        }

        if (rd < st)
        {
            res = -1;
            break;
        }

        res ++;

        if (rd >= ed)
        {
            success = true;
            break;
        }


        st = rd;
        i = j - 1;

    }

    if (success) cout << res << endl;
    else cout << -1 << endl;


    return 0;
}