会场安排问题

在这里插入图片描述

问题描述

Description

假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的贪心算法进行安排。(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小会场数。)
对于给定的k个待安排的活动,计算使用最少会场的时间表。

Input

输入数据的第一行有1
个正整数k(k≤10000),表示有k个待安排的活动。接下来的k行中,每行有2个正整数,分别表示k个待安排的活动开始时间和结束时间。时间以0
点开始的分钟计。

Output

输出一个整数,表示最少会场数。

Sample Input-1

5 1 23 12 28 25 35 27 80 36 50

Sample Output-1

3

Sample Input-2

6 8 32 18 48 16 82 83 84 39 89 90 98

Sample Output-2

3

思路

这是刚讲完贪心布置的题目,然后我就按贪心做,总是错,才知道用贪心只能局部最优。

**------------------------
具体详情请点击这里,看这篇文章
**------------------------

这题不用贪心,我们先把所有活动按开始时间升序排,然后依次往会场里面放,我们用一维数组a表示会场,每个数组存的是会场中最后一个活动的结束时间,我们只需要将活动开始时间与数组值(即最后一个活动结束时间)比较,相容就放进去,不相同就比较其他会场,如果都不行,就开一个新的会场。

AC代码


#include <iostream>
#include <memory.h>
#include <algorithm>
using namespace std;

//活动结构体
struct Activity {
    int start;//活动开始时间
    int end;//活动结束时间
} activity[10010];//最多有10000个活动,我们多一丢丢

//a[i]存第i个会场最后一个活动结束时间
int a[10010];//假设我们有10010个会场,不一定都会用到
int pointer = 0;//存已经用了多少会场

//按活动开始时间升序排序
bool cmp( Activity a, Activity b ) {
    return a.start < b.start;
}

//活动安排函数
void Arrange( int n ) {
    int j;

    //遍历每一个活动
    for( int i = 0; i < n; i++ ) {
        //遍历每一个会场,看能不能排
        for( j = 0; j <= pointer; j++ ) {
            //活动开始时间>=当前会场最后一个活动的结束时间,可以排
            if( activity[i].start >= a[j] ) {
                //更新数组值,即会场结束时间
                a[j] = activity[i].end;
                break;
            }
        }

        //遍历所有会场,没有找到空闲的,另外开一个新会场
        if( j == pointer + 1 ) {
            pointer++;
            //新会场数组存活动结束时间
            a[pointer] = activity[i].end;
        }
    }
}

int main() {
    int n;
    cin >> n;

    for( int i = 0; i < n; i++ ) {
        cin >> activity[i].start >> activity[i].end;
    }

    //初始化所有数组值为0,是为了方便第一个活动放入
    memset( a, 0, sizeof( 0 ) );

    //按活动开始时间升序排序
    sort( activity, activity + n, cmp );

    Arrange( n );

    cout << pointer + 1 << endl;

}
/*
两组测试数据
第一组:
6
8 32
18 48
16 82
83 84
39 89
90 98

第二组:
5
1 23
12 28
25 35
27 80
36 50
*/

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值