关于贪心算法:https://blog.csdn.net/qq_40452317/article/details/88875193
活动安排问题就是要在所给的活动集合中选出最大的相容活动子集合。该问题要求高效地安排一系列争用某一公共资源的活动。贪心算法提供了一个简单、漂亮的方法使得尽可能多的活动能兼容地使用公共资源。
问题描述和分析
设有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相容。
活动安排问题: 要在所给的活动集合中选出最大的相容活动子集合。
活动安排问题的关键是如何按照一定的顺序安排活动,使得选出的活动间相容并能安排尽量多的活动。
例:
设待安排的11个活动的开始时间和结束时间按结束时间的非减序排列如下:
i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
S[i] | 1 | 3 | 0 | 5 | 3 | 5 | 6 | 8 | 8 | 2 | 12 |
f[i] | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
由于输入的活动以其完成时间的非减序排列,所以每次总是选择具有最早完成时间的相容活动加入集合A中。直观上,按这种方法选择相容活动为未安排活动留下尽可能多的时间。也就是说,贪心选择的意义是使剩余的可安排时间段极大化,以便安排尽可能多的相容活动。
若被检查的活动i的开始时间Si小于最近选择的活动j的结束时间fi,则不选择活动i,否则选择活动i加入集合A中。
贪心算法并不总能求得问题的整体最优解。但对于活动安排问题,贪心算法greedySelector却总能求得的整体最优解,即它最终所确定的相容活动集合A的规模最大。这个结论可以用数学归纳法证明。
代码
#include<iostream>
using namespace std;
int s[12]={0,1,3,0,5,3,5,6,8,8,2,12},f[12]={0,4,5,6,7,8,9,10,11,12,13,14};
bool a[11];
int n=11;
int Selector()
{
a[1]=true;
int j=1;
int count=1;
for (int i=2;i<=n;i++)
{
if(s[i]>=f[j])
{
a[i]=true;
j=i;
count++;
}
else
a[i]=false;
}
return count;
}
int main()
{
cout<<"活动序号:"<<endl;
for(int i=1;i<=11;i++)
cout<<i<<" ";
cout<<endl<<"活动开始时间:"<<endl;
for(int i=1;i<=11;i++)
cout<<s[i]<<" ";
cout<<endl<<"活动结束时间:"<<endl;
for(int i=1;i<=11;i++)
cout<<f[i]<<" ";
int count=Selector();
cout<<endl<<"一共选择个"<<count<<"活动如下:"<<endl;
for(int i=0;i<=n;i++)
if(a[i])
cout<<i<<" ";
return 0;
}