P1047 [NOIP2005 普及组] 校门外的树

算法:区间调度

入门的例子:

        有一间教室,一堆人申请使用,如何安排可以满足最多的人的要求(给定每个人的开始时间、持续时间)

思路:

        乍一看这道题是需要我们求给定的区间内有多少棵树(也确实如此),由于存在重叠的线段,如果用暴力破解(定义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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值