BZOJ 3410 [Usaco2009 Dec]Selfish Grazing 自私的食草者:贪心【最多线段覆盖】
题目链接:http://begin.lydsy.com/JudgeOnline/problem.php?id=1324
题意:
给你n个区间,问你最多能选择多少个区间使得它们不相互覆盖。
题解:
RQNOJ 569 Milking Time中,每个线段有权值,所以要用dp。
而这道题问的是最多区间数,只是数量,对于每一个区间都一样。所以可以贪心。
贪心目标:
为了让总区间数最多,所以应该让某一段范围内的区间数最多。
贪心策略:
(1)对于当前已覆盖范围(0,pos),再选一个区间时,在保证能放的前提下,应让这个区间的rig最小。
(2)对于当前已覆盖范围(0,pos),最后一次选的区间的lef应尽可能大。
所以只用考虑rig不同,lef最大的区间。挑出来再贪心。
AC Code:
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 #include <algorithm> 5 #include <vector> 6 #define MAX_N 50005 7 8 using namespace std; 9 10 struct Cow 11 { 12 int lef; 13 int rig; 14 Cow(int _lef,int _rig) 15 { 16 lef=_lef; 17 rig=_rig; 18 } 19 Cow(){} 20 void read_cow() 21 { 22 cin>>lef>>rig; 23 } 24 friend bool operator < (const Cow &a,const Cow &b) 25 { 26 return a.rig!=b.rig?a.rig<b.rig:a.lef>b.lef; 27 } 28 }; 29 30 int n; 31 Cow cow[MAX_N]; 32 vector<Cow> v; 33 34 int main() 35 { 36 cin>>n; 37 for(int i=0;i<n;i++) 38 { 39 cow[i].read_cow(); 40 } 41 sort(cow,cow+n); 42 for(int i=0;i<n;i++) 43 { 44 if(i==0 || cow[i].rig!=cow[i-1].rig) 45 { 46 v.push_back(cow[i]); 47 } 48 } 49 int pos=0; 50 int ans=0; 51 for(int i=0;i<v.size();i++) 52 { 53 Cow now=v[i]; 54 if(now.lef>=pos) 55 { 56 pos=now.rig; 57 ans++; 58 } 59 } 60 cout<<ans<<endl; 61 }