贪心 区间覆盖最小值

贪心 区间覆盖最小值

POJ 2376

大概题意: 从1到T区间内,必须保证每个点都有牛在工作,给出每头牛的工作时间,求需用到的最小的牛的数量,无解输出-1
一开始以为组合[1,4] [5,T]不算覆盖,要[1,4],[4,T]才可以,卡了一下午。。。蠢哭
思路就是先按区间左l排序,先确定第一个区间,我们的原则是左边相同,右边越大越好。同样的,找区间右边可以接上的区间(下个区间的l<=本区间r),循环然后找r最大的区间,这样才可以尽量少用区间嘛,注意跳出条件。

#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=25000+5;
struct Edge
{
	int l,r;
	bool operator<(const Edge &rhs)const{
		return (l<rhs.l)||((l==rhs.l)&&(r>rhs.r));
	}
}t[N];
int main() 
{
	int n,T;
	cin>>n>>T;
	int l,r;
	for(int i=0;i<n;i++){
		cin>>l>>r;
		if(l<r){
			t[i].l=l;
			t[i].r=r;
		}else{
			t[i].l=r;
			t[i].r=l;
		}
	}
	sort(t,t+n);
	int le=0,ri=0,cnt=0,i=0;//le左界
	while(i<n){
		le=ri+1;   //这就是我卡了一下的地方,注意可以不叠加。。。
		while(t[i].l<=le){  //在所有满足下个区间的l<=本区间r,循环然后找r最大的区间
			if(ri<t[i].r){
				ri=t[i].r;
			}
			i++;
		}		
		if(ri>=le){//这里条件说明我们找到了一个符合条件的区间,因为最初始le=ri+1
			cnt++;
			if(ri>=T){//跳出条件
				break;
			}	
			i--;//因为我们跳出上个while是因为这个区间的l>本区间r,我们ri还没改,那么下次这个区间还需要用
		}
		i++;//没找到继续循环
	}	
	if(ri>=T){
		cout<<cnt<<endl;
	}else{
		cout<<-1<<endl;
	}
	return 0;
}

posted @ 2018-10-13 21:57  Janspiry  阅读(209)  评论(0编辑  收藏  举报