贪心算法 活动安排 C++代码

问题描述

设有n个活动的集合 E = {1,2,…,n},其中每个活动都要求使用同一资源,如演讲,会议等,而在同一时间内只有一个活动能使用这一资源。

每个活动i都有一个要求使用该资源的起始时间s[i]和一个结束时间f[i],且 s[i] <f[i]。如果选择了活动i,则它在半开时间区间 [s[i] ,f[i]) 内占用资源。若区间[s[i]] , f[i])与区间[s[j], f[j])不相交,则称活动i与活动j是相容的。当s[i]≥f[j]或s[j]≥f[i]时,活动i与活动j相容。

活动安排问题就是在所给的活动集合中选出最大的相容活动子集合。

数据

在这里插入图片描述

算法策略:

活动结束早的优先选,排序使f[1]<f[2]<f[3]<…<f[n],从前向后挑选活动

代码

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// 面向对象方法解决问题
struct Activity 
{
	int begin_time;// 开始时间
	int end_time;// 结束时间

	Activity(int b, int e) :begin_time(b), end_time(e) {}
	
	// 重载运算符<
	// 根据活动的结束时间早晚进行比较
	bool operator < (Activity a)
	{
		return (this->end_time < a.end_time)
	}
};

// 重载运算符<<
// 打印活动开始时间和结束时间
ostream& operator<<(ostream &cout_, Activity a)
{
	cout_ << "活动开始时间为:" << a.begin_time << "活动结束时间为:" << a.end_time;
	return cout_;
}

/*
	@param act_sets 活动集合
	@return 最大相容活动子集
*/
vector<int> ArrangeActivity(vector<Activity> act_sets)
{
	vector<int> res_sets;
	int current_time = 0;// 记录当前时间
	int activity_index = 0;

	while (activity_index != act_sets.size())
	{
		// 上一个被安排活动的结束时间小于当前活动的开始时间
		if (current_time <= act_sets[activity_index].begin_time)
		{
			// 添加当前活动编号
			res_sets.push_back(activity_index + 1);
			// 记录下当前活动结束时间
			current_time = act_sets[activity_index].end_time;
		}
		// 继续判断下一个活动是否符合安排条件
		activity_index++;
	}
	return res_sets;
}

int main()
{
	// 准备数据
	vector<Activity> act_sets = { Activity(1,4),Activity(8, 12),Activity(0,6)\
		, Activity(3, 5), Activity(3, 8), Activity(2, 13), Activity(5, 9)\
		, Activity(8, 11), Activity(6, 10), Activity(5, 7), Activity(12, 14) };

	// 根据活动的结束时间从早到晚对活动进行排序
	sort(act_sets.begin(), act_sets.end());
	//for (int i = 0; i < act_sets.size(); ++i)
	//	cout << act_sets[i] << endl;

	vector<int> res = ArrangeActivity(act_sets);

	cout << "最大相容活动子集为:" << endl;
	for (int i = 0; i < res.size(); ++i)
		cout << res[i] << " ";

	return 0;
}


  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值