SDUT 1298-活动选择(贪心)

Description
学校的大学生艺术中心周日将面向全校各个学院的学生社团开放,但活动中心同时只能供一个社团活动使用,并且每一个社团活动开始后都不能中断。现在各个社团都提交了他们使用该中心的活动计划(即活动的开始时刻和截止时刻)。请设计一个算法来找到一个最佳的分配序列,以能够在大学生艺术中心安排不冲突的尽可能多的社团活动。
比如有5个活动,开始与截止时刻分别为:
在这里插入图片描述
最佳安排序列为:1,4,5。
Input
第一行输入活动数目n(0<n<100);
以后输入n行,分别输入序号为1到n的活动使用中心的开始时刻a与截止时刻b(a,b为整数且0<=a,b<24,a,b输入以空格分隔)。
Output
输出最佳安排序列所包含的各个活动(按照活动被安排的次序,两个活动之间用逗号分隔)。
Sample
Input
6
8 10
9 16
11 16
14 15
10 14
7 11
Output
1,5,4

题目大意:一共有n个活动,每个活动都有开始时间和活动时间,要求输出最佳的活动安排,即活动与活动之间不能有冲突,且可用的活动数最多。

解题思路:这是一道贪心的题目,因为我们要尽可能多的安排活动而且不能有冲突,我们可以先按结束时间给他排序,第一个活动结束的时间一定是最早的,最后一个活动结束的时间一定是最晚的,我们先用一个结构体来存每个活动,结构体里有三个元素:开始时间,结束时间,活动编号(因为拍排序以后原来的编号就乱了,所以我们用一个变量存储原来的编号)。因为已经排好序了,所以我们判断当前活动的开始时间是否大于等于上一个活动的结束时间,如果是则说明这个活动可以进行,并把上一个结束时间更新为当前活动的结束时间,每次选择最优解,最后依次输出序号即可。AC代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>

using namespace std;

const int N = 110;

struct Act {
    int id, st, ed;
    
    bool operator < (const Act &t) {//题目要求字典序,没有这步会WA
        if (ed == t.ed) return id < t.id;
        return ed < t.ed;
    }
};

int n;
Act act[N];

int main() {
    scanf("%d", &n);
    
    for (int i = 1; i <= n; i ++) {
        scanf("%d%d", &act[i].st, &act[i].ed);
        act[i].id = i;
    }
    
    sort(act + 1, act + 1 + n);
    
    int end = -2e9;
    vector<int > res;
    for (int i = 1; i <= n; i ++)
        if (end == -2e9 || act[i].st >= end) {
            res.push_back(act[i].id);
            end = act[i].ed;
        }
    for (int i = 0; i < res.size(); i ++)
        printf(i == 0 ? "%d" : ",%d", res[i]);
    puts("");
    
    return 0;
}
posted @ 2020-03-16 23:01  Hayasaka  阅读(93)  评论(0编辑  收藏  举报