贪心
把线段们按终止点b的先后排序,b小的在前面,b一样随便
然后设r为当前最大的b
每加入一条新的线段i,判断是否重合(i.a>=r)
如果重合就舍弃i,否则把i加入,ans++,更新r:r=i.b
证明:
加入有这样几条线段:
1:------
2: ----
3: ------------
4: ---------------
请问1、2、3是重合的,你选那条?
一定是选b最小的1,因为那样对后面选线段的影响就尽量小,就有可能选到更多线段(比如4,而一开始选3就不行)
代码:
#include<iostream> #include<algorithm> #define Size 105 using namespace std; int n; struct L{ int a,b; }d[Size]; bool cnt(L x,L y){ return x.b<y.b; //b小的在前面,b一样随便 } int main(){ freopen("1214.in","r",stdin); cin>>n; int x,y; for(int i=1;i<=n;i++){ cin>>x>>y; if(x>y)swap(x,y); d[i].a=x; d[i].b=y; } sort(d+1,d+1+n,cnt); int r=-0x3f3f3f3f; int ans=0; for(int i=1;i<=n;i++){ if(d[i].a>=r){ //cout<<i<<endl; ans++; r=d[i].b; } } cout<<ans<<endl; fclose(stdin); return 0; }