一、求最大不相交区间的数目
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct node{
int l,r;
bool operator< (const node &n)const{
return r<n.r;
}
};
int main(){
int n;
scanf("%d",&n);
node a[N];
for(int i=0;i<n;i++){
int l,r;
scanf("%d%d",&l,&r);
a[i]={l,r};
}
sort(a,a+n);
int ans=0,ed=-2e9;
for(int i=0;i<n;i++){
if(a[i].l>ed){
ans++;ed=a[i].r;
}
}
printf("%d",ans);
return 0;
}
二、区间分组
题目描述:给定n个闭区间,分为若干组(组内任意区间无交集),使组数最小。
思路:
1.将所有区间按左端点排序。
2.从左到右处理区间:
判断能否放入某个组内(L<=max_r):
1.不存在,开新组
2.若存在,放入组中,并更新max_r.
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct node{
int l,r;
bool operator< (const node &n)const{
return l<n.l;
}
};
priority_queue <int,vector<int>,greater<int> > heap; //小根堆维护max_r的值
int main(){
int n;
scanf("%d",&n);
node a[N];
for(int i=0;i<n;i++){
int l,r;
scanf("%d%d",&l,&r);
a[i]={l,r};
}
sort(a,a+n);
int res=0;
for(int i=0;i<n;i++){
if(heap.empty()||heap.top()>=a[i].l){
heap.push(a[i].r);
}
else{
heap.pop();
heap.push(a[i].r);
}
}
printf("%d",heap.size());
return 0;
}
三、区间覆盖
问题描述:给定一个大区间,以及n个小区间,求最少多少个小区间可以完全覆盖大区间。
思路:
1.将所有区间按左端点从小到大排序。
2.从前先后遍历,从能覆盖start的区间中选择右端点最大的一个区间,并将右端点更新为start。
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
struct node{
int l,r;
bool operator< (const node &n)const{
return l<n.l;
}
};
int main(){
int n,s,t;
scanf("%d%d%d",&s,&t,&n);
node a[N];
for(int i=0;i<n;i++){
int l,r;
scanf("%d%d",&l,&r);
a[i]={l,r};
}
sort(a,a+n);
int res=0;
int fg=0;
for(int i=0;i<n;i++){
int j=i,r=-2e9;
while(j<=n&&a[j].r>=s){
j++;
r=max(r,a[i].r);
}
if(r<s){
res=-1;break;
}
res++;
if(r>=ed){
fg=1;break;
}
st=r;
i=j-1;
}
if(!fg) res=-1;
printf("%d",res);
return 0;
}