大意就是给出n个线段,让你在n个线段里面选出尽可能多的不相交的线段。
思路:

  ... 1    2    3    4    5    6    7    8    9   10   11   12   13 ...
  ... |----|----|----|----|----|----|----|----|----|----|----|----|----
Cow 1:      <===:===>          :              :              :
Cow 2: <========:==============:==============:=============>:
Cow 3:          :     <====>   :              :              :
Cow 4:          :              :     <========:===>          :
Cow 5:          :              :     <==>     :              :

贪心。
贪心策略:
1.看图可以发现先贪右边界大的区间,如果后面的区间i放不下,也就是和刚选择的区间重合了(选择的区间按题目要求是不重合的,所以和i重合的已选区间就一个),图给我们的灵感是,如果区间i的左边界比已选的大,那么区间i一定比已选的区间更优,要用i替代那个已选区间,也就是给程序一个反悔的机会,替换后的区间依旧互不重合,而且左边的范围更大了,满足局部最优就是全局最优。
2.好像贪心左区间最小的也行。
考虑第一种策略:
1.按右边界降序排序,右边界相同就按左边界升序排序,左边界升序排序是为了减少替换的操作。
2.如果区间i不会和已选区间重合,直接加入。
3.如果区间i会和已选区间重合且比已选区间更优,那么就用i替换掉已选区间。

Code:

#include<bits/stdc++.h>
#define  js  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
typedef long long ll;
struct node{
    int x,y;
    bool operator<(const node&a) const{
        if(y==a.y) return x<a.x;
        return y>a.y;
    }
}q[50005];
int main() {
    js; int n,ans=1;
    cin>>n;
    for(int i=1;i<=n;++i) cin>>q[i].x>>q[i].y;
    sort(q+1,q+1+n);
    for(int i=2,pos=1;i<=n;++i) {
        if(q[i].y<=q[pos].x) {
            ++ans;
            pos=i;
        }
        else if(q[i].x>q[pos].x) pos=i;
    }
    cout<<ans<<"\n";
}