贪心策略:会议安排

贪心策略:会议安排

高级钟点秘书:会议安排

所谓“钟点秘书”,是指年轻白领女性利用工余时间为客户提供秘书服务,并按钟点收取酬金。
“钟点秘书”为客户提供有偿服务的方式一般是:采用电话、电传、上网等“遥控”式服务,或亲自到客户公司处理部分业务。其服务对象主要有三类:一是外地前来考察商务经营、项目投资的商人或政要人员,他们由于初来乍到,急需有经验和熟悉本地情况的秘书帮忙;二是前来开展短暂商务活动,或召开小型资讯发布会的国外客商;三是本地一些请不起长期秘书的企、事业单位。这些客户普遍认为:请“钟点秘书”,一则可免去专门租楼请人的大笔开销;二则可根据开展的商务活动请有某方面专长的可用人才;三则由于对方是临时雇用关系,工作效率往往比固定的秘书更高。据调查,在上海“钟点秘书”的行情日趋看好。对此,业内人士认为:为了便于管理,各大城市有必要组建若干家“钟点秘书服务公司”,通过会员制的形式,为众多客户提供规范、优良、全面的服务,这也是建设国际化大都市所必需的。
某跨国公司总裁正分身无术,为一大堆会议时间表焦头烂额,希望高级钟点秘书能做出合理的安排,能在有限的时间内召开更多的会议。

在有限的时间内开更多的会议,且不能同时进行两场会议,因此,我们需要用到贪心策略:
策略1:选择开始时间与上一场结束时间相同的会议,即保证空闲时间尽可能少,会议一场接着一场
策略2:优先排出耗费时间最短的会议,然后再依次选择耗费时间逐步提升的会议
策略3:选择具有最早结束时间且与已安排会议相容的会议,如果一场会议都没安排则选择所有会议中结束时间最早的会议。
究竟应该选择哪种策略呢?如果选择第一种策略,我们并没有考虑会议持续时间的因素,显然是不合理的。题目要求的只是会议数量尽可能多,因此不能只考虑时间的因素。第二种策略有点类似于Kruskal算法,优先选用时间最少的会议,再排开,但是这个算法并没有考虑到空闲时间要素,只考虑会议时间而不考虑空闲时间的缩短也是不合理的。那我们再来看看第三种算法:从剩下的会议中选择具有最早结束时间且与当前会议不冲突的会议。这种算法基于明确的从开始到结束的时间,可以按照时间的顺序找到耗费时间最短且不冲突的会议,因此,策略3是最合理的。
算法概括:把所有会议按照结束时间递增排序,首先选择结束时间最早的会议,接着在不冲突的情况下选择结束时间尽可能早的会议。
详细过程:
1.选择第一个会议,第一个会议就是全部会议中结束时间最早的会议。
2.依次从剩下未安排的会议中选择,先选择结束时间最早的,如果会议开始时间要迟于上一个会议的结束时间,则安排这个会议;如果开始时间早于上一个,则放弃,选择下一个。
3.直到一天的时间结束,排出安排最多数量的会议的方案。
因此,我们需要定义一个结构体,包含会议的三个基本要素:会议编号,开始时间,结束时间;在将所有会议按照结束时间排序后,依次选择具有最早结束时间且相容的会议,最后打印结果。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct Meet
{
	int begin;
	int end;
	int num;
}meet[1000];
class setMeet
{
public:
	void init();
	void solve();
private:
	int n, ans; //n:会议总数 ans:最大的安排会议总数
};
//读入数据
void setMeet::init()
{
	int s, e;
	cout << "输入会议总数:" << endl;
	cin >> n;
	int i;
	cout << "输入每个会议的开始时间和结束时间:" << endl;
	for (i = 0; i < n; i++)
	{
		cin >> s >> e;
		meet[i].begin = s;
		meet[i].end = e;
		meet[i].num = i + 1;
	}
}

bool cmp(Meet x, Meet y)
{
	if (x.end == y.end)
		return x.begin > y.begin;
	return x.end < y.end;
}

void setMeet::solve()
{
	sort(meet, meet + n, cmp); //对会议按结束时间排序
	cout << "排序后的会议时间如下: " << endl;
	int i;
	cout << "会议编号" << "     开始时间 " << " 结束时间" << endl;
	for (i = 0; i < n; i++)
	{
		cout << "  " << meet[i].num << "\t\t" << meet[i].begin << "\t" << meet[i].end << endl;
	}
	cout << "-------------------------------------------" << endl;
	cout << "选择会议的过程:" << endl;
	cout << "选择第" << meet[0].num << "个会议" << endl; //选中了第一个会议
	ans = 1;
	int last = meet[0].end;
	for (i = 0; i < n; i++)
	{
		if (meet[i].begin >= last)  //如果会议i开始时间大于等于最后一个选中的会议的结束时间
		{
			ans++;
			last = meet[i].end;
			cout << "选择第" << meet[i].num << "个会议" << endl;
		}
	}
	cout << "最多可以安排" << ans << "个会议" << endl;
}

int main()
{
	setMeet sm;
	sm.init(); //读入数据
	sm.solve();//贪心算法求解
	return 0;
}

在第一个函数中,循环输入每一个会议的开始和结束时间;在第二个函数中,运用一个循环结构,循环判断每个会议是否与已安排的会议相容。
运行结果:
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值