1. 程式人生 > >區間覆蓋問題 例題 POJ 2376

區間覆蓋問題 例題 POJ 2376

題意:給出N個區間[Li,Ri],選最少數量的區間使得給定區間[l,r]被覆蓋。

分析:

貪心經典例題。

將區間按左端點(相同則按右端點)排序,直接用pair就可以。

curR表示當前已經覆蓋到的區間右端點,已經討論到i號區間。

那麼  求出滿足s[i].x <= R+1 (如果區間是實數區間,這裡要注意精度差) 的 s[i].y的最大值Max。

如果Max<=curR表示不能再移動,也就是無解了

curR移動到Max,ans++(表示用了一個新區間)。

如果curR>=R,就表示覆蓋完畢。

程式碼如下:

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>

#define PII pair<int,int>
#define xx first
#define yy second

using namespace std;
const int maxn=30000+5,inf=0x3f3f3f3f;

int n,T;
PII s[maxn];

template <typename T>
inline void _read(T &x){
    char ch=getchar(); bool mark=false;
    for(;!isdigit(ch);ch=getchar())if(ch=='-')mark=true;
    for(x=0;isdigit(ch);ch=getchar())x=x*10+ch-'0';
    if(mark)x=-x;
}

int main(){
    int i;
    _read(n);_read(T);
    for(i=1;i<=n;i++)
    	_read(s[i].xx),_read(s[i].yy);
    sort(s+1,s+1+n);
    int R=0,ans=0;
    i=1;
    while(true){
    	int Max=-1;
    	while(i<=n && s[i].xx<=R+1)
    		Max=max(Max,s[i].yy),i++;
    	if(Max<=R){
    		puts("-1");
    		return 0;
    	}
    	else R=Max,ans++;
    	if(R>=T){
    		cout<<ans<<endl;
    		return 0;
    	}
    }
    return 0;
}