Acwing 907. 区间覆盖 区间贪心

75 阅读1分钟

907. 区间覆盖 - AcWing题库

拿样例举例,我们发现只需要两段备用区间就可以覆盖掉原区间: image.png

思想

我们每次都选最长的一段的备选区间,这样就能用最少的备选区间覆盖原区间: image.png image.png

code

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
typedef pair<int,int> PII;
  vector<PII> seg;
  
  bool cmp(PII x , PII y){
    return x.second < y.second;
}
int main() {
    int st, ed;
    cin >> st >> ed;

    int n;
    cin >> n;
  
       while(n--)
       {
          PII x;
        cin >> x.first>> x.second;
        seg.push_back(x);
       }
        for (int i = 0; i < n; i++) {
        PII x;
        cin >> x.first >> x.second;
        seg.push_back(x);
    }
    
     
   

    // 按左端点排序
    sort(seg.begin(), seg.end(),cmp);

    bool is_success = false;
    int i = 0, cnt = 0;
    while (i < n) {
        int rmax = -2e9;  // 维护右端点的最大值
        while (i < n && seg[i].first<= st) {  // 在左端点<=st的区间中,选择右端点最大的一个
            rmax = max(rmax , seg[i].second);
            i ++;
        }

        // 如果最大右端点rmax小于st,则没有能覆盖st这个点的区间了,返回false
        if (rmax < st) {
            is_success = false;
            break;
        }
        else if (rmax >= st) {  // 说明[st,rmax]这里面的点被覆盖住了
            // 选择右端点最大的那个区间用来覆盖[st,rmax]上的点
            st = rmax; //更新start到右端点位置
            cnt ++;
            if (rmax >= ed) {
                is_success = true;
                break;
            }
        }
    }

    if (is_success == false) cout << -1 << endl;
    else cout << cnt << endl;

    return 0;
}

注意事项: 我用while循环结果不对,用for循环结果才对: image.png image.png