小sun的假期(贪心+逻辑思维)

在这里插入图片描述
这道题一看就是区间排序,但是怎么把没有安排的区间记录这就有点困难了;
区间排序按照这样排序:

bool cmp(Node a,Node b){
	  if(a.l==b.l)return a.r<b.r;//如果左区间相等,就按照右区间从小到大排序
	  else return a.l<b.l;//左区间不相等,那么久按照左边,从小到大排序;
}

举个例子,如果我这个区间经过排序成了这样:
在这里插入图片描述
我初始化,l和r分别为1和0;我用for(0:n-1)那么如果r<L1那么l就应该先记录max(ans,L1-l),之后再把l指向r+1,然后再把r指向R1;如果r>L2那么就把r指向R2去,同理这样一直指到R4,然后由于r<L5了,所以就把l指向r+1的地方,最后r指向R5;
所以最后要求一下n-r的值;为什么l要初始化为1呢?因为如果刚开始区间是1开头的,那么L1-l就是0;所以这样就可以把前面的抵消掉;
这样就可以贪心出来了,主要是这里的逻辑很不好理清;
确实巧妙!!!

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
pair<int,int> p[100050];
int main(){
		  int n,m;
		  scanf("%d %d",&n,&m);
           for(int i=0;i<m;i++){
        	   scanf("%d %d",&p[i].first,&p[i].second);
		   }
		   sort(p,p+m);//利用pair的默认排序
		   int L=1;
		   int ans=0;
		   int r=0;
		   for(int i=0;i<m;i++){
		   	  if(r<p[i].first){//
		   	  	    ans=max(ans,p[i].first-L);
		   	  	    L=r+1;//先移动左区间
		   	  	    r=p[i].second;//再移动右区间
				 }else if(r>p[i].first){
				 	r=max(r,p[i].second);
				 }
		   }
		   printf("%d\n",max(ans,n-r));//因为最后r指向的是最后的区间,所以这里需要比较一下n-r和ans 的大小
	return 0;
} 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值