贪心算法之会议安排(2021/1/18)

问题引入

在这里插入图片描述

代码实现

//会议时间表
//会议       1   2   3   4   5   6   7   8   9   10
//开始时间   8   9   10  11  13  14  15  17  18  26  
//结束时间   10  11  15  14  16  17  17  18  20  19
//贪心策略:局部最优解,选择结束最早的
//相容且最早结束
#include<iostream>
using namespace std;
struct Meeting{
	int num;//会议序号 
	float start;//会议开始时间 
	float end;//会议结束时间
	int flag;//记录是否被选中 
};
void printMeeting(struct Meeting*meet,int n){
	int i=0;
	if(!meet||n<=0){
		return;
	}
	for(i=0;i<n;i++){
		printf("DATA:%d:\n",meet[i].num);
		printf("\tstart:%f\n",meet[i].start);
		printf("\tend:%f\n",meet[i].end);
		printf("\tflag:%d\n",meet[i].flag);
	}
} 
int main(int argc,char**argv){
	int i=0,j=0;
	//建立数组存储会议信息
	struct Meeting meet[10]={
		{1,8,10,0},
		{2,9,11,0},
		{3,10,15,0},
		{4,11,14,0},
		{5,13,16,0},
		{6,14,17,0},
		{7,15,17,0},
		{8,17,18,0},
		{9,18,20,0},
		{10,16,19,0}
	};
	//信息输出
	printMeeting(meet,10);
	//我们既然要选择结束最早的,那么我们最好以end将meet进行排序,以便操作
	//在此为了,便于操作数据较少,采用了冒泡排序
	//如果对时间复杂度要求严格,可改进排序算法
	for(i=0;i<10;i++){
		for(j=0;j<10-i-1;j++){
			if(meet[j].end>meet[j+1].end){
				struct Meeting temp=meet[j];
				meet[j]=meet[j+1];
				meet[j+1]=temp;
			}
		}
	}
	//排序后输出
	printf("进行排序后\n");
	printMeeting(meet,10);
	//存储可利用时间段信息
	int time_start=8,time_end=20;
	//开始进行贪心选择
	int now=time_start;//记录可以用时间段的开始时间
	for(i=0;i<10;i++){
		if(meet[i].start>=now&&meet[i].end<=time_end){
			meet[i].flag=1;//选中
			now=meet[i].end;//更新now 
		}else if(meet[i].end>time_end){
			break;
		} 
	}
	//输出会议安排序列
	printf("会议序列为:\n");
	for(i=0;i<10;i++){
		if(meet[i].flag){
			printf("\t%d",meet[i].num);
		}
	} 
	//可见会议安排问题的解并不唯一,当多个会议的end相同
	//且都相容时,我们对其不同选择,会产生不同的结果
	//此题还可能为:1 4 7 8 9 ,同样有5个会议
	//我们可以将一些会议加上权重值,进而解决这种问题 
	return 0;
} 

程序输出

DATA:1:
        start:8.000000
        end:10.000000
        flag:0
DATA:2:
        start:9.000000
        end:11.000000
        flag:0
DATA:3:
        start:10.000000
        end:15.000000
        flag:0
DATA:4:
        start:11.000000
        end:14.000000
        flag:0
DATA:5:
        start:13.000000
        end:16.000000
        flag:0
DATA:6:
        start:14.000000
        end:17.000000
        flag:0
DATA:7:
        start:15.000000
        end:17.000000
        flag:0
DATA:8:
        start:17.000000
        end:18.000000
        flag:0
DATA:9:
        start:18.000000
        end:20.000000
        flag:0
DATA:10:
        start:16.000000
        end:19.000000
        flag:0
进行排序后
DATA:1:
        start:8.000000
        end:10.000000
        flag:0
DATA:2:
        start:9.000000
        end:11.000000
        flag:0
DATA:4:
        start:11.000000
        end:14.000000
        flag:0
DATA:3:
        start:10.000000
        end:15.000000
        flag:0
DATA:5:
        start:13.000000
        end:16.000000
        flag:0
DATA:6:
        start:14.000000
        end:17.000000
        flag:0
DATA:7:
        start:15.000000
        end:17.000000
        flag:0
DATA:8:
        start:17.000000
        end:18.000000
        flag:0
DATA:10:
        start:16.000000
        end:19.000000
        flag:0
DATA:9:
        start:18.000000
        end:20.000000
        flag:0
会议序列为:
        1    4       6    8       9
--------------------------------
Process exited after 0.1396 seconds with return value 0
请按任意键继续. . .
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

高万禄

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值