会场安排问题

会场安排问题

问题描述

有一个会议室,同时只能被一个会议使用。现在有n个会议申请,每个申请给出了会议开始时间、结束时间。问如何安排,才能使最多的会议召开。

方法

  • 将n个会议按开始时间从早到晚排序。
  • 将第一个会议选入。
  • 之后的第i个会议,设开始时间为 s i s_i si,结束时间为 f i f_i fi,设上一个被选入的会议开始时间为 s p r e s_{pre} spre,结束时间为 f p r e f_{pre} fpre
  1. s i > = f p r e s_i>=f_{pre} si>=fpre,则将第i个会议选入,即 p r e = i pre=i pre=i
    理由:这种情况说明,第i个会议没有和已选入的会议产生时间冲突。已经将开始时间从早到晚排序,那么,i之后的会议更不会和选入的的会议冲突(因为开会时间更晚了)。会议 p r e pre pre被选入的结果不可能再改变,将 i i i作为新的 p r e pre pre的值。
  2. s i < f p r e 且 f i > = f p r e s_i<f_{pre}且f_i>=f_{pre} si<fprefi>=fpre,则放弃第i个会议。
    理由:这说明,第i个会议和已选入的一个会议有冲突。这时有两种方法:放弃会议 i i i或者放弃会议 p r e pre pre。会议 i i i p r e pre pre的权重相同(都是一次会议),由于会议 i i i的结束时间晚于会议 p r e pre pre,所以选择会议 p r e pre pre,放弃 i i i。因为早点结束,之后有更多的选择。
  3. s i < f p r e 且 f i < f p r e s_i<f_{pre}且f_i<f_{pre} si<fprefi<fpre,则放弃第 p r e pre pre个会议,选择会议 i i i
    理由:和第二条理由相同, 因 为 f i < f p r e 因为f_{i}<f_{pre} fi<fpre,所以, [ f i , e n d ] [f_i,end] [fiend]的时间段内可以召开的会议必然不少于 [ f p r e , e n d ] [f_{pre},end] [fpreend]时间段内召开的会议数。

代码

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=1e4;
struct N{int b,e,ind;}a[maxn];
int n,pre=1,st[maxn],tot;

bool cmp(const N &a,const N &b){return a.b<b.b;}

int main(){
    printf("请输入会议数量:");
    scanf("%d",&n);
    printf("依次输入%d个会议的起始时间,结束时间\n",n);
    for(int i=1;i<=n;i++)   scanf("%d%d",&a[i].b,&a[i].e),a[i].ind=i;
    sort(a+1,a+n+1,cmp);
    st[tot++]=1;
    for(int i=2;i<=n;i++)
        if(a[i].b>=a[pre].e)   st[tot++]=i,pre=i;
        else if(a[i].e<a[pre].e)    st[tot-1]=i,pre=i;
    printf("最多可以安排%d个会议\n一种可以选择的方案是:",tot);
    for(int i=0;i<tot;i++)
        printf("会议%d%c",a[st[i]].ind,i==tot-1?'\n':' ');
}

测试样例

5
1 6
2 7
3 8
4 5
5 6

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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
会场安排问题贪心算法的核心思想是选择局部最优解,即在最少的会场安排足够多的活动。算法的具体步骤如下: 1. 将待安排的活动按照结束时间的先后顺序进行排序。 2. 初始化一个安排的空闲时间段为0,表示当前没有任何会场安排活动。 3. 遍历排好序的活动列表,对于每个活动: - 如果当前活动的开始时间大于当前可安排的空闲时间段的结束时间,并且该活动未被安排过,则将该活动加入该会场,并更新当前可安排的空闲时间段为该活动的结束时间。 - 如果当前活动的开始时间小于等于当前可安排的空闲时间段的结束时间,表示该活动和已安排的活动有冲突,需要安排到下一个会场。 4. 遍历一次后,使用的会场数即为最少会场数。 下面是一个案例代码的示例: ```cpp #include<iostream> #include<cstdio> using namespace std; struct Activity { int start, end; bool scheduled; }; int arrange(int k, Activity *activities) { int count = k, room_avail = 0, room_num = 0; while (count > 0) { for (int i = 0; i < k; i++) { if (activities[i].start > room_avail && !activities[i].scheduled) { room_avail = activities[i].end; activities[i].scheduled = true; count--; } } room_avail = 0; room_num++; } return room_num; } int main() { int k, room_num; cin >> k; Activity activities[k]; for (int i = 0; i < k; i++) { cin >> activities[i].start >> activities[i].end; activities[i].scheduled = false; } room_num = arrange(k, activities); cout << room_num << endl; return 0; } ``` 这个算法会将活动按照结束时间的先后顺序进行排序,然后遍历每个活动,选择合适的会场进行安排,直到所有的活动都被安排完毕。最终输出的结果是使用最少会场数的时间表。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [会场安排问题贪心算法)](https://blog.csdn.net/weixin_43553142/article/details/103571130)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

m0_51864047

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

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

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

打赏作者

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

抵扣说明:

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

余额充值