1.问题
设有n个活动的集合E={1,2,…,n},其中每个活动都要求使用同一资源,如演讲会场等,而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi,且si <fi 。如果选择了活动i,则它在半开时间区间[si, fi)内占用资源。若区间[si, fi)与区间[sj, fj)不相交,则称活动i与活动j是相容的。也就是说,当si≥fj或sj≥fi时,活动i与活动j相容。
目标是尽可能选择更多的会议来使用资源。
2.解析
1.选择最早开始时间且不与已安排会议重叠的会议
2.选择使用时间最短且不与已安排会议重叠的会议
3.选择最早结束时间且不与已安排会议重叠的会议
三个贪心策略中应该选择第三个,因为在这道题的情景之下,贪心的对象应该转化为使剩余时间的可安排时间段尽可能大,以便之后的会议能够有更多的时间来进行。
3.设计
//A存储的是成对信息 A[i]代表的是第i个会议
//有两个属性,begin开始时间,end结束时间
//num代表的是一共有多少个会议
ARRANGE_MEETING(A,num)
SORT_ASC(A) //根据end结束时间进行降序排序,如果end相同,则根据begin来进行排序
NOW_END = A[0].end //选择第一个会议
CNT=1 //记录选择了几个会议
for i = 1 to num:
if A[i].begin >= NOW_END:
NOW_END = A[i].end
CNT++
return CNT;
4.分析
1.时间复杂度由两部分构成,分别是排序所需要的时间以及遍历一遍所需要的时间。
排序的复杂度跟采用的算法有关,如果采用冒泡排序,那么复杂度为O(n2);如果采用的是快速排序,那么排序部分复杂度为O(nlog(n))。
遍历一遍所用的时间为O(n)。
因为这里直接用的是STL中的快速排序,所以总体的时间复杂度为:O(nlog(n))
2.因为空间只用了一个变量,所以空间复杂度为O(1) 。
5.完整代码
#include <bits/stdc++.h>
const int maxn = 1000;
using namespace std;
int num;
struct meeting
{
int b_time;
int e_time;
meeting()
{
b_time = 0;
e_time = 0;
}
};
meeting m[maxn];
queue<meeting> record;
bool cmp(meeting m1, meeting m2)
{
if(m1.e_time == m2.e_time)
return m1.b_time < m2.b_time;
else
return m1.e_time < m2.e_time;
}
int main()
{
cout << "Input the number of the meeting:";
cin >> num;
for(int i = 0 ; i < num; i++){
cin >> m[i].b_time >> m[i].e_time;
}
sort(m,m+num,cmp);
for(int i = 0 ; i < num ; i++){
cout << m[i].b_time << "," << m[i].e_time << endl;
}
int now_e_time = m[0].e_time;
int cnt = 1;
record.push(m[0]);
for(int i = 1 ; i < num ; i++)
{
if(m[i].b_time > now_e_time)
{
now_e_time = m[i].e_time;
cnt++;
record.push(m[i]);
}
}
cout << "Max number of the meeting:" << cnt << endl;
while(!record.empty())
{
meeting head = record.front();
record.pop();
cout << head.b_time << "," << head.e_time << endl;
}
return 0;
}
版权声明:本文为qq_43403657原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。