贪心 区间覆盖最小值
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;
}