大意就是给出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";
} 
京公网安备 11010502036488号