[ CodeVS冲杯之路 ] P1214
不充钱,你怎么AC?
题目:http://codevs.cn/problem/1214/
这道题类似于最长区间覆盖,仅仅是将最长区间改成了最多线段,我们贪心即可
先将线段直接右边-1,然后按左边为第一关键字,右边为第二关键字升序排序,我们发现对于以下这种情况,是可以直接将黑色的线段删除的,因为要求线段最多,也就是每个区间要最小。
最后从左往右扫,卡一个最右端点,遇到大于右端点的就更新,时间复杂度 O(n2),删线段可以优化到 nlog2n 但是 n 只有100就懒得打了~
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<cmath> 5 #include<iostream> 6 #include<algorithm> 7 #define N 101 8 using namespace std; 9 10 struct line 11 { 12 int l,r; 13 } 14 a[N]; 15 bool f[N]; 16 int n,ans; 17 bool cmp(line x,line y) 18 { 19 return (x.l<y.l)||((x.l==y.l)&&(x.r<y.r)); 20 } 21 int main() 22 { 23 int i,j; 24 scanf("%d",&n); 25 for (i=1;i<=n;i++) 26 { 27 scanf("%d%d",&a[i].l,&a[i].r); 28 if (a[i].l>a[i].r) swap(a[i].l,a[i].r); 29 a[i].r--; 30 f[i]=0; 31 } 32 sort(a+1,a+1+n,cmp); 33 for (i=1;i<n;i++) 34 { 35 for (j=i+1;j<=n;j++) 36 { 37 if (a[j].l>a[i].r) break; 38 if (a[j].r<=a[i].r) 39 { 40 f[i]=1; 41 break; 42 } 43 } 44 } 45 j=-100000; 46 for (i=1;i<=n;i++) 47 { 48 if (f[i]||a[i].l<=j) continue; 49 ans++; 50 j=a[i].r; 51 } 52 printf("%d\n",ans); 53 return 0; 54 }