题意:给定n个区间,求一个点集S,使每个区间最少有两个元素在s中。
思路就是贪心咯,按区间的终止点(右边的点)从小到大排列,我们每次取区间最右边的点(所取的几个点是最优的),使这个区间内至少有两个点在s中,贪心的证明很简单,在纸上画一画就出来了。
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
using namespace std;
#define MAXN 10100
struct Node{
int x,y;
}node[MAXN];
bool cmp(const Node& a,const Node& b)
{
return a.y<b.y;
}
int main()
{
int n,i,j,tmp,index,arr[MAXN],n_ans,n_cnt,ans;
while(scanf("%d",&n)!=EOF)
{
memset(arr,0,sizeof(arr));
for(i = 0;i < n; ++i)
scanf("%d%d",&node[i].x,&node[i].y);
sort(node,node+n,cmp);
n_ans = node[0].y-1;
arr[node[0].y] = arr[node[0].y-1] = 1;
ans = 2;
for(i = 0;i < n; ++i)
{
n_cnt = 0;
if(node[i].x<=n_ans)
continue;
for(j = node[i].x;j <= node[i].y; ++j)
{
if(arr[j])
++n_cnt;
if(n_cnt==2)
break;
}
if(n_cnt == 1)
{
++ans;
arr[node[i].y] = 1;
}
if(n_cnt == 0)
{
arr[node[i].y] = 1;
arr[node[i].y-1] = 1;
ans += 2;
}
}
printf("%d\n",ans);
}
return 0;
}