简洁来说,会议安排指的是在有限的时间内召开更多会议(两个会议不能同时进行)。会议安排问题本质就是贪心算法的使用。
下面进入正题:
会议时间表
会议i | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
开始时间bi | 3 | 1 | 5 | 2 | 5 | 3 | 8 | 6 | 8 | 12 |
结束时间ei | 6 | 4 | 7 | 5 | 9 | 8 | 11 | 10 | 12 | 14 |
问题目标:求在14时间内最多的会议个数。
做本题的策略就是找到最早开始的时间+持续时间最短的时间的会议。其实就是找到 最早结束时间的会议 。即对结束时间进行排序(由小到大),如果结束时间相同,那么按照会议开始的时间先后排序(由大到小,结束时间固定,时间越大代表持续时间越短)。
排完顺序后,结束时间越早,就意味着持续时间越短。按照顺序排除不成立事件,即会议开始时间早于上一个会议的结束时间的事件,剩余的就是成立的会议,用计数器记下来即可。
排序后表格如下:
会议i | 2 | 4 | 1 | 3 | 6 | 5 | 8 | 7 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|
开始时间bi | 1 | 2 | 3 | 5 | 3 | 5 | 6 | 8 | 8 | 12 |
结束时间ei | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 14 |
这里应用结构体存数据:会议开始时间,会议结束时间,记录会议编号(第几场会议);
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个会议