1. 程式人生 > >poj 1716 貪心(整數區間:2-覆蓋)

poj 1716 貪心(整數區間:2-覆蓋)

題意:給定n個區間[pi.s,pi.t],現要選出一個數據集合S,使得每個區間至少有兩個元素在S中。求集合S的最小元素個數。

思路:貪心,按照區間的末端排序。設定兩個遊標表示當前取得的兩個數a和b。對p[i]分三種情況討論:

1、p[i].s<=a,則不需要改變a和b,因為a和b能夠覆蓋p[i].a~p[i].b;

2、p[i].s>a && p[i].s<=b。b保留,再加入p[i].b。即a = b,b = p[i].t;

3、p[i].s>b。ab均不能覆蓋p[i],所以更新a=p[i].t-1,b=p[i].t;

#include <stdio.h>
#include <stdlib.h>
#define N 10005
struct node{
	int s,t;
}p[N];
int n;
int cmp(const void *a,const void *b){
	return (*(struct node*)a).t - (*(struct node*)b).t;
}
int main(){
	freopen("a.txt","r",stdin);
	while(scanf("%d",&n)!=EOF){
		int i,a,b,res=2;
		for(i = 0;i<n;i++)
			scanf("%d %d",&p[i].s,&p[i].t);
		qsort(p,n,sizeof(struct node),cmp);
		a = p[0].t-1;
		b = p[0].t;
		for(i = 1;i<n;i++){
			if(p[i].s <= a)
				continue;
			if(p[i].s <= b){
				a = b;
				b = p[i].t;
				res++;
			}
			else if(p[i].s > b){
				a = p[i].t-1;
				b = p[i].t;
				res += 2;
			}
		}
		printf("%d\n",res);
	}
	return 0;
}