AcWing 905. 区间选点
思路:
按照右端点排序,记录一个当前的选点值,如果遍历到的区间左端点大于选点值,那么就更新这个值到右端点,并且记录更新次数。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
struct range{
int r,l;
bool operator< (range &a) const
{
return r<a.r;
}
}a[N];
int main() {
int n;
cin>>n;
for(int i = 0;i<n;i++)
{
scanf("%d%d",&a[i].l,&a[i].r);
}
sort(a,a+n);//按照右端点排序
int cnt = 0;
int ed = -1e9;
for(int i = 0;i<n;i++){
int r = a[i].r;
int l = a[i].l;
if(ed<l) {
ed = r;
cnt++;
}
}
cout<<cnt;
return 0;
}
最大不相交区间
思路同上,证明使用将假设的最佳答案一步步变成我们算法求出来的答案。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5+10;
int n;
struct Range{
int l,r;
bool operator<(const Range &a) const{
return r<a.r;
}
}range[N];
int main() {
cin>>n;
for(int i =0;i<n;i++)
scanf("%d%d",&range[i].l,&range[i].r);
sort(range,range+n);
int cnt = 0,ed = -2e9+10;
for(int i = 0;i<n;i++){
// cout<<ed<<' '<<range[i].l<<endl;
if(ed<range[i].l){
ed = range[i].r;
cnt++;
}
}
cout<<cnt;
return 0;
}
区间分组
思路
首先将所有区间按照左端点排序,然后依次考虑每一个区间的分组,如果该区间能被加入到分组中, 那么就加入,如果不能就新建一个分组。
代码
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
const int N = 1e5+10;
struct Range{
int l,r;
bool operator<(const Range &a) const{
return l<a.l;
}
}range[N];
int n;
priority_queue<int,vector<int>,greater<int>> q;
int main() {
cin>>n;
for(int i = 0;i<n;i++){
scanf("%d%d",&range[i].l,&range[i].r);
}
sort(range,range+n);
for(int i = 0;i<n;i++){
bool flag = false;
if(q.empty()){
}
else if(q.top()<range[i].l){
q.pop();
q.push(range[i].r);
flag = true;
}
if(!flag){
q.push(range[i].r);
}
}
cout<<q.size();
return 0;
}
区间覆盖
思路
首先将所有的区间按照左端点排序,再依次选择符合条件,但是右端点最长的区间。
代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5+10,INF = 2e9+10;
struct Range{
int l,r;
bool operator<(const Range &a) const{
return l<a.l;
}
}range[N];
int n;
int main() {
int s,t;
cin>>s>>t;
cin>>n;
for(int i = 0;i<n;i++){
scanf("%d%d",&range[i].l,&range[i].r);
}//读入
sort(range,range+n);
int ans = 0;
int st = s,ed = -INF;
int flag = false;
for(int i = 0;i<n;i++){
if(range[i].l>st)
{
flag = true;
break; }
if(ed>=t)
break;
ed = range[i].r;
for(int j = i+1;j<n&&range[j].l<=st;j++){
if(range[j].r>=ed){
i = j;
ed = range[j].r;
}
}
st = ed;
// cout<<ed<<endl;
ans++;
}
if(flag ||ed<t){
cout<<-1;
}else{
cout<<ans;
}
return 0;
}