简单的会议安排问题

简洁来说,会议安排指的是在有限的时间内召开更多会议(两个会议不能同时进行)。会议安排问题本质就是贪心算法的使用。
下面进入正题:

会议时间表

会议i12345678910
开始时间bi31525386812
结束时间ei64759811101214

问题目标:求在14时间内最多的会议个数
做本题的策略就是找到最早开始的时间+持续时间最短的时间的会议。其实就是找到 最早结束时间的会议 。即对结束时间进行排序(由小到大),如果结束时间相同,那么按照会议开始的时间先后排序(由大到小,结束时间固定,时间越大代表持续时间越短)。
排完顺序后,结束时间越早,就意味着持续时间越短。按照顺序排除不成立事件,即会议开始时间早于上一个会议的结束时间的事件,剩余的就是成立的会议,用计数器记下来即可。
排序后表格如下:

会议i24136587910
开始时间bi12353568812
结束时间ei45678910111214

这里应用结构体存数据:会议开始时间,会议结束时间,记录会议编号(第几场会议);

struct Meet{
    int beg;//记录会议开始时间
    int end;//记录结束时间;
    int num;//记录会议编号;
}meet[1000];

示例数据

10
3 6
1 4
5 7
2 5
5 9
3 8
8 11
6 10
8 12
12 14

数据输入

 cin>>sum;//数据数量
 for(i=1;i<=sum;i++)
 {
        cin>>meet[i].beg>>meet[i].end;
        meet[i].num=i;//num是编号
  }

排序:

bool cmp(Meet a,Meet b)
{//对结束时间进行排序(由小到大),如果结束时间相同,那么按照会议开始的时间先后排序
//(由大到小,结束时间固定,时间越大代表持续时间越短)。
    if(a.end==b.end)
        return a.beg>b.beg;//beg是开始时间,end是结束时间
    else
    return a.end<b.end;
}
sort(meet+1,meet+sum+1,cmp);//因为我是从 i=1 开始存的,如果数据输入中i=1更改为i=0,则排序为sort(meet,meet+sum,cmp);

last代表当前会议的结束时间,初始值为:

int last=meet[1].end;//如果i是从0开始的,则初始值为int last=meet[0].end

对所有数据进行遍历,当会议开始时间大于等于当前会议结束时间,更新last数据,ans++(会议个数++);
排完顺序后,结束时间越早,就意味着持续时间越短。按照顺序排除不成立事件,即会议开始时间早于上一个会议的结束时间的事件,剩余的就是成立的会议,用计数器记下来即可。
具体代码如下:

for(i=2;i<=sum;i++)
    {
        if(meet[i].beg>=last)
        {
            ans++;
            last=meet[i].end;
            cout<<"选择第"<<meet[i].num<<"个会议"<<endl;
        }

    }

全部代码如下:

#include <iostream>
#include<algorithm>
#include<cstring>
using namespace std;
struct Meet{
    int beg;//记录会议开始时间
    int end;//记录结束时间;
    int num;//记录会议编号;
}meet[1000];
bool cmp(Meet a,Meet b)
{
    if(a.end==b.end)
        return a.beg>b.beg;
    else
    return a.end<b.end;
}
int main()
{
    int i,j,k,sum,count=0;
    cout<< "请输入会议总数"<<endl;
    cin>>sum;
    cout<< "输入会议开始的时间和结束的时间,以空格分开"<<endl;
    for(i=1;i<=sum;i++)
        cin>>meet[i].beg>>meet[i].end,meet[i].num=i;
    sort(meet+1,meet+sum+1,cmp);
    cout<< "排完序的会议时间如下"<<endl;
    cout<< "--------------------------------------------------------"<<endl;
    for(i=1;i<=sum;i++)
    cout <<" "<<meet[i].num<<"\t\t"<<meet[i].beg<<"\t"<<meet[i].end<<endl;
    int last=meet[1].end;
    cout<<"选择第"<<meet[1].num<<"个会议"<<endl;
    int ans=1;
    for(i=2;i<=sum;i++)
    {
        if(meet[i].beg>=last)
        {
            ans++;
            last=meet[i].end;
            cout<<"选择第"<<meet[i].num<<"个会议"<<endl;
        }

    }
    cout<<"最多安排"<<ans<<"个会议"<<endl;
    return 0;
}

样例输出:

排完序的会议时间如下
--------------------------------------------------------
 2              1       4
 4              2       5
 1              3       6
 3              5       7
 6              3       8
 5              5       9
 8              6       10
 7              8       11
 9              8       12
 10             12      14
选择第2个会议
选择第3个会议
选择第7个会议
选择第10个会议
最多安排4个会议
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值