题意
找到能覆盖全部区间范围的最小子区间数,没有则输出-1
题解
- 对区间按起点升序排序,起点相同则按终点升序排序。(排序后才可以用贪心,因为起点大的在已覆盖区间中时,那么起点小的一定也在,此时只要比较谁的终点大即可)
- 寻找最佳的子区间(区间的终点最远且起点在当前已覆盖区间的范围内),终止条件是:当前子区间的下一个子区间不在已覆盖区间范围内
- 更新当前已覆盖区间(变量now)
注意: 在区间的条件是:[now.from, now.to+1]
代码
#include <iostream>
#include <algorithm>
#define MAXN 100000
#define INF 0x7fffffff
using namespace std;
struct Line
{
int from;
int to;
};
Line line[MAXN];
struct compare
{
bool operator()(Line l1,Line l2)
{
if(l1.from < l2.from)
return true;
if(l1.from == l2.from && l1.to < l2.to)
return true;
else
return false;
}
};
int n,m;
int solve()
{
int cnt = 0;
int flag = 0;
line[n].from = INF;
Line now;
now.from = 0;
now.to = 0;
int last = 0;
for(int i = 0 ;i < n; i++)
{
if(line[i].from <= now.to + 1 && line[i].to > last) //find a line with max len in interval
{
last = line[i].to;
flag = 1;
}
if(flag && line[i+1].from > now.to + 1) //flag means has find a proper interval
{
now.to = last;
flag = 0;
cnt++;
}
}
if(last < m)
cnt = -1;
return cnt;
}
int main()
{
cin>>n>>m;
for(int i = 0; i < n; i++)
cin>>line[i].from>>line[i].to;
sort(line,line+n, compare());
cout<< solve() <<endl;
}