Description
假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的贪心算法进行安排。(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小会场数。) 对于给定的k个待安排的活动,计算使用最少会场的时间表。
Input
输入数据的第一行有1 个正整数k(k≤10000),表示有k个待安排的活动。接下来的k行中,每行有2个正整数,分别表示k个待安排的活动开始时间和结束时间。时间以0 点开始的分钟计。
Output
输出一个整数,表示最少会场数。
Sample Input
5
1 23
12 28
25 35
27 80
36 50
Sample Output
3
将开始时间和结束时间分别存为一个数组
然后进行降序排序
从第i个活动开始时间与第j个活动结束时间作比较
如果开始时间大于等于结束时间,说明不用增加会场,就当第j个活动结束了,然后j++
开始时间小于结束时间时,需要增加会场,ans++,第j个活动可以当还没结束,所以j不用动,直到遇到开始时间大于等于第j个活动结束时间的
算法时间复杂度:$O(nlogn)$
c++,sort:
#include <iostream>
#include <algorithm>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n, i, Begins[10002], Ends[10002]; // Begins开始时间, Ends结束时间
cin >> n;
for (i = 0; i < n; i++)
cin >> Begins[i] >> Ends[i];
sort(Begins, Begins + n); // 升序排序
sort(Ends, Ends + n); // 升序排序
int j = 0, ans = 0;
for (i = 0; i < n; i++)
if (Begins[i] < Ends[j]) // 如果开始时间小于结束时间, 会场数加1
ans++;
else // 开始时间大于等于结束时间, 会场不用增加, 换下一家活动
j++;
cout << ans << endl;
return 0;
}
c,qsort:
#include <stdio.h>
#include <stdlib.h>
int cmp(const void* a, const void* b)
{
return *(int *)a - *(int *)b;
}
int main()
{
int n, i, begins[10002], ends[10002];
scanf("%d", &n);
for (i = 0; i < n; i++)
scanf("%d%d", &begins[i], &ends[i]);
qsort(begins, n, sizeof(int), cmp);
qsort(ends, n, sizeof(int), cmp);
int j = 0, ans = 0;
for (i = 0; i < n; i++)
if(begins[i] < ends[j])
ans++;
else
j++;
printf("%d
", ans);
return 0;
}
还有一种时间复杂度$O(n^2)$的方法;
比活动安排问题多出一个数组用来存储会场当前的状况
#include <bits/stdc++.h>
using namespace std;
struct Activity
{
int begin; // 开始时间
int end; // 结束时间
}activity[10002]; // 活动
bool cmp(Activity a, Activity b)
{
return a.begin < b.begin;
}
int conference[10002]; // 会场
int main()
{
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n;
cin >> n;
for (int i = 0; i < n; i++)
cin >> activity[i].begin >> activity[i].end;
sort(activity, activity + n, cmp); // 按开始时间升序排序
int ans = 0;
for (int i = 0; i < n; i++)
{
int temp = ans;
for (int j = 0; j <= temp; j++) // 从已经有的会场找需不需要新会场, 不需要就更新结束时间
{
if (activity[i].begin >= conference[j])
{
if (conference[j] == 0) // 需要新会场
ans++;
conference[j] = activity[i].end; // 更新会场结束时间
break;
}
}
}
cout << ans << endl;
return 0;
}