飞道的博客

活动安排(贪心算法)C/C++

408人阅读  评论(0)


样例输入
4 10
1 3
2 4
5 7
9 10
样例输出
3

下面看一下一个贪心算法的典型例题
活动选择问题

有n个需要在同一天使用同一个教室的活动a1,a2,…,an,教室同一时刻只能由一个活动使用。每个活动ai都有一个开始时间si和结束时间fi 。一旦被选择后,活动ai就占据半开时间区间[si,fi)。如果[si,fi]和[sj,fj]互不重叠,ai和aj两个活动就可以被安排在这一天。该问题就是要安排这些活动使得尽量多的活动能不冲突的举行。例如下图所示的活动集合S,其中各项活动按照结束时间单调递增排序。

考虑使用贪心算法的解法。为了方便,我们用不同颜色的线条代表每个活动,线条的长度就是活动所占据的时间段,蓝色的线条表示我们已经选择的活动;红色的线条表示我们没有选择的活动。
如果我们每次都选择开始时间最早的活动,不能得到最优解:

如果我们每次都选择持续时间最短的活动,不能得到最优解:

可以用数学归纳法证明,我们的贪心策略应该是每次选取结束时间最早的活动。直观上也很好理解,按这种方法选择相容活动为未安排活动留下尽可能多的时间。这也是把各项活动按照结束时间单调递增排序的原因。

通过代码如下:

#include<iostream>
#include<algorithm>
using namespace std;

struct aa
{
   
	int start ;
	int end ;
};

bool cmp(aa x,aa y)
{
   
	return x.end<=y.end;
}


void greedychoose(int n,int m,aa a[])
{
   
	int s=1,i=1;
	for( int j=2;j<=n;j++ )
	{
   
		if(a[j].start>=a[i].end&&a[j].end<=m)
		{
   
			i=j;
			s++;
		}
	}
	cout << s << endl ;
}


int main()
{
   
	int n,m,i=1;
	cin >> n ;
	cin >> m ;
	aa time[n+5] ;
	while(i<=n)
	{
   
		cin >> time[i].start >> time[i].end ;
		i++;
	}
	sort(time+1,time+n,cmp);
	//验证排序是否完成
	/*for(int j=1;j<=n;j++)
	{
		cout << time[j].start << " " << time[j].end << endl ;
	}*/
	greedychoose(n,m,time);
}

转载:https://blog.csdn.net/wangyurenwls/article/details/116952481
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场