题目的分析被说得有点绕。自己理解是这样,首先由题目我们知道选择的区间都是相互不相交的,除这之外,我们的目标是尽量的让选择的区间达到最大化。
所以我们可以先对齐排序,因为输入是随机的。假设每个区间表示为(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;
}