區間覆蓋問題 例題 POJ 2376
阿新 • • 發佈:2018-12-24
題意:給出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; }