会场安排问题

会场安排问题

问题描述

有一个会议室,同时只能被一个会议使用。现在有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
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

m0_51864047

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

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

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

打赏作者

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

抵扣说明:

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

余额充值