其他分享
首页 > 其他分享> > 贪心三类区间问题方法总结 (未完)

贪心三类区间问题方法总结 (未完)

作者:互联网

区间选点问题

数轴上有N个闭区间[Ai, Bi]。取尽量少的点,使得每个区间内都至少有一个点(不同区间内含的点可以是同一个)。

思路

1.按左端点递增排序,如果左端点相同,就按右端点递增排序。
2.从第一个区间的右端点开始
2. 1.如果后一个区间的左端点大于了第一个区间的右端点,就说明还不能覆盖,答案累加一,并把右端点的覆盖距离更新.
2. 2如果后一个区间的左端点小于第一个区间的右端点,说明可以覆盖,再把右端点的覆盖距离更新.

#include <cstdio>
#include <algorithm>
using namespace std;
void read(int &x) {
	x = 0;
	int f = 1;
	char s = getchar();
	while (s < '0' || s > '9' ) {
		if(s == '-') {
			f = -1;
		}
		s = getchar();
	}
	while(s >= '0' && s<= '9') {
		x = x*10 + (s - 48);
		s = getchar();
	}
	x *= f;
}
int n;
struct node {
	int start, end;
} q[100005];
bool cmp (node a, node b) {
	if (a.x == b.x) return a.y < b.y;
	else return a.x < b.x;
}

int main() {
	read(n);
	for(int i = 1;i <= n;i ++) {
		read(q[i].start);
		read(q[i].end);
	}
	sort(q+1,q+1+n,cmp);
//	for(int i = 1;i <= n;i ++) {
//		printf("\n%d %d", q[i].start, q[i].end);
//	}
	int sum,E;
	sum = 1,E = 1;
	for(int i = 2;i <= n;i ++) {
		if(q[i].start > q[E].end) {
			sum ++;
			E = i;
		}
	}
	printf("%d", sum);
	return 0;
} 

区间完全覆盖问题

给定一个长度为m的区间,再给出n条线段的起点和终点,求最少使用多少条线段可以将整个区间完全覆盖。

思路

1、将每一条线段按左端点递增顺序排列,如果左端点相同,按右端点递增顺序排列。
2、end表示已覆盖到的区间右端点,在剩下的线段中找出所有左端点小于等于当前已覆盖到的区间右端点的线段,选择右端点最大并且大于当前已覆盖到的区间右端点,重复以上操作直至覆盖整个区间;

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 1e6 + 5; 

int n, s, t, end, beg, k, ans, maxl;
bool flag;

struct node {
	int x, y;
} a[MAXN];
bool cmp (node a, node b) {
	if (a.x == b.x) return a.y < b.y;
	else return a.x < b.x;
}

int main() {
	scanf ("%d %d %d", &n, &s, &t);
	for (int i = 1; i <= n; i++) {
		scanf ("%d %d", &a[i].x, &a[i].y);
	}
	sort (a + 1, a + 1 + n, cmp);
	end = s, beg = 0, k = 1;
	while (end < t) {
		maxl = 0;
		for (k = beg; k <= n && a[k].x <= end; k++) {
			maxl = max(maxl, a[k].y);
		}
		if (maxl > end) {
			end = maxl;
			beg = k;
			ans ++;
		} else {
			flag = 1;
			break;
		}
	}
	if (flag) {
		printf ("No Solution\n");
	} else printf ("%d\n", ans);
	return 0;
}

区间划分问题

时间轴上有n个开区间(ai, bi),把这些区间至少划分成多少个集合,使得每个集合中的区间两两没有公共点。因为是开区间,所以(1, 2)和(2,3)可在一个集合中。

标签:总结,三类,end,覆盖,int,端点,区间,include,贪心
来源: https://www.cnblogs.com/cqbz-ChenJiage/p/13654918.html