选择不相交区间(贪心算法) By ACReaper

题目的分析被说得有点绕。自己理解是这样,首先由题目我们知道选择的区间都是相互不相交的,除这之外,我们的目标是尽量的让选择的区间达到最大化。

所以我们可以先对齐排序,因为输入是随机的。假设每个区间表示为(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;
} 

    原文作者:贪心算法
    原文地址: https://blog.csdn.net/sixleaves/article/details/8762882
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞