贪心算法训练(二)——活动安排(选择不相交区间问题)
-
问题描述
-
设有 n 个活动的集合 E = {1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只能有一个活动能使用这一资源。每个活动 i 都有一个要求使用该资源的起始时间 si 和一个结束时间 fi ,且 si < fi ,要求设计程序,使得安排的活动最多
i 1 2 3 4 5 6 7 8 9 10 11 Starti 1 3 0 5 3 5 6 8 8 2 12 Endi 4 5 6 7 8 9 10 11 12 13 14
-
-
问题分析
- 求最大相容活动子集,即区间上不互斥的所有活动,比如 1 和 2 就是互斥的,不可能同时发生,因为 1 还没结束, 2 已经需要开始了
- 那么如何设计算法,即把数据时间按照互动结束时间从小到大排序,尽量满足结束时间的紧凑性,然后判断开始时间,如果不满足相容活动子集,舍去
-
代码
#include <iostream>
using namespace std;
void sort(double* start_time,double *end_time,int n);
int main()
{
int n = 11;
double temp[n];
double name[n];
double start_time[n],end_time[n];
for(int i = 0;i<n ;i++)
cin>>start_time[i]>>end_time[i];
sort(start_time,end_time,n);
int j = 0,k = 0;
while(j<n)
{
if(j == 0)
{
temp[k] = end_time[j];
name[k] = j + 1;
k++;
}
else
{
if(start_time[j] > temp[k-1])
{
name[k] = j + 1;
temp[k] = end_time[j];
k++;
}
}
j++;
}
for(int i = 0;i<k;i++)
cout<<name[i]<<" 号的表演,结束时间为 "<<temp[i]<<endl;
return 0;
}
void sort(double *start_time,double *end_time,int n)
{
for(int i = 0;i<n-1;i++)
{
for(int j = 0;j<n-i-1;j++)
{
if(end_time[j] > end_time[j+1]){
swap(end_time[j],end_time[j+1]);
swap(start_time[j],start_time[j+1]);
}
}
}
}
-
数据
1 4
3 5
0 6
5 7
3 8
5 9
6 10
8 11
8 12
2 13
12 14