算法:区间调度
入门的例子:
有一间教室,一堆人申请使用,如何安排可以满足最多的人的要求(给定每个人的开始时间、持续时间)
思路:
乍一看这道题是需要我们求给定的区间内有多少棵树(也确实如此),由于存在重叠的线段,如果用暴力破解(定义flag,处理过这个区间置为1,每处理一个区间都判断一个区间),大概率会超时。
上面的例子和这道题很相似,都是对区间数据进行处理。
此题:本质是使多个区间,变为最简的区间(区间合并,如 [ 1 , 3 ] , [ 2 , 4 ] , [ 3 , 5 ] 合并为 [ 1 , 5 ] )。
flag区间表示 [ p , q ]
- 对区间按 p 的大小升序排序
- 判断新区间的 p 在不在上一个区间的范围内
- 在则合并,更新 q 为 max{ q, 新区间q }
- 不在则结算区间,另起一个flag的 p 、q 更新为新区间的 p 、q
AC代码:
#include <bits/stdc++.h>
using namespace std;
struct tree{
int fir,last;
};
bool cmp(tree a,tree b){
return a.fir<b.fir;
}
int main(){
int l,m;
cin>>l>>m;
vector<tree>v;
for(int i=0;i<m;i++){
tree temp;cin>>temp.fir>>temp.last;
v.push_back(temp);
}
sort(v.begin(),v.end(),cmp);
l++;
int p=v[0].fir,q=v[0].last;
for(int i=1;i<m;i++){
if(v[i].fir>q){
l=l-(q-p+1);
p=v[i].fir;
q=v[i].last;
}else{
q=max(q,v[i].last);
}
if(i==m-1){
l=l-(q-p+1);
}
}
cout<<l;
}