题目的分析被说得有点绕。自己理解是这样,首先由题目我们知道选择的区间都是相互不相交的,除这之外,我们的目标是尽量的让选择的区间达到最大化。
所以我们可以先对齐排序,因为输入是随机的。假设每个区间表示为(x,y)我们可以选择按照x排序所有区间,也可以选择按照y来排序所有区间。而不管选择哪一个来排序,其原理和本质都一样,都是为了方便操作,将其有序化。
我们这里选择按照y来排序,排序完后有y1 <= y2 <= y3.......
现在我们讨论x1 x2 ....
当x1 > x2时,区间被x2这个区间包含,所以选择x1这个区间更为划算。
而当x1 < x2时,当x2 > y1时,区间互不相交,先选x1区间,接着选x2区间
当x1 < x2 && x2 <=y1 时,两个区间相交,这时,如果选择了x2区间,就不能选择x1区间,反之亦然。
但要选择哪一个呢?我们知道如果不选x2也就是选x1,则我们此时把x1分成两半部分,一部分在x2内,如果选择了x2,x2区间不仅包含了x1的,还可能包含x3区间的,因为x2的长度肯定大于或等于x1区间的长度,也就是说从概率上讲,选x2肯定不如选x1划算。
综上所述:这个问题第一次一定要选择x1,接着就是把相交部分去掉,循环选不想交的。
#include <stdio.h>typedef struct zone{int x;int y;
}zone;
zone A[1000];
//快速排序接口
int partition(zone A[],int st,int ed){zone key = A[st];int j = st;for(int i = st + 1; i <= ed; i++){if(A[i].y <= key.y){j++;zone temp = A[i];A[i] = A[j];A[j] = temp;}}zone temp = A[j];A[j] = A[st];A[st] = temp;return j;
}
void quicksort(zone A[],int st,int ed){if(st < ed){int mid = partition(A,st,ed);quicksort(A,mid + 1,ed);quicksort(A,st,mid - 1);}}
//快速排序接口
#define MAXN 1000
int path[MAXN];
int main(){int n;while(scanf("%d",&n) != EOF){for(int i = 0 ; i < n; i++){scanf("%d%d",&A[i].x,&A[i].y);//input (x,y) } quicksort(A,0,n - 1);int len = 0,i = 1;zone key = A[0];path[len++] = 0;while(i < n){if(key.y < A[i].x){//true 则把A[i]拓展进来 path[len++] = i;key = A[i]; } i++;}for(int i = 0; i < len; i++){printf("(%d,%d) ",A[path[i]].x,A[path[i]].y);}}return 0;
}