UVa 10020 - Minimal coverage

題目:有n條線段,從裡面取出最少的將區間0,M]覆盖上。

分析:貪心,會議安排類似物。按左端點排序,每次取能夠覆蓋的右端點最大的值即可。

說明:╮(╯▽╰)╭。

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstdio>

using namespace std;

typedef struct _segment
{
	int l, r, select;
}segment;
segment S[100001];

int cmp(segment s1, segment s2)
{
	if (s1.l == s2.l)
		return s1.r > s2.r;
	return s1.l < s2.l;
}

int main()
{
	int N, M;
	while (scanf("%d",&N) != EOF)  
	while (N --) {
		scanf("%d",&M);
		int count = 0;
		while (~scanf("%d%d",&S[count].l,&S[count].r)) {
			if (!S[count].l && !S[count].r) break;
			S[count ++].select = 0;
		}
		
		sort(S, S+count, cmp);
		
		int sum = 0, Rvalue = 0, now = 0;
		while (now < count && Rvalue < M) {
			int max = now, flag = 0;
			while (Rvalue >= S[now].l && now < count) {
				if (S[max].r <= S[now].r) {
					max = now;
					flag = 1;
				}
				++ now;
			}
			
			if (flag) {
				Rvalue = S[max].r;
				S[max].select = 1;
				sum ++;
			}else break;
		}
		
		if (Rvalue < M || S[0].l > 0)
			puts("0");
		else {
			printf("%d\n",sum);
			for (int i = 0; i < count; ++ i)
				if (S[i].select)
					printf("%d %d\n",S[i].l,S[i].r);
		}
		if (N) puts("");
	}
	return 0;
}


你可能感兴趣的:(UVa 10020 - Minimal coverage)