SDUT 1298 活动选择(贪心)
Problem 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
Sample Output
1,5,4
AC代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
bool cmp(struct Activity a, struct Activity b);
struct Activity {
int head, rear, tag; //开始 截止时间 活动序号
}Act[102];
int main() {
int N; cin >> N; //活动数目
for (int i = 0; i < N; i++) { //得到每个活动的开始及截止时间
scanf("%d %d", &Act[i].head, &Act[i].rear);
Act[i].tag = i + 1; //从1开始标号
}
sort(Act, Act + N, cmp); //按照结束时间升序排列
int Ret[102]; //记录结果活动序号
int pos = 1;
Ret[0] = Act[0].tag; //将最早结束的活动放入决策
int Truth = Act[0].rear; //Truth指决策中最新的活动截止时间
for (int i = 1; i < N; i++) {
if (Act[i].head >= Truth) { //满足活动选择
Ret[pos++] = Act[i].tag;
Truth = Act[i].rear; //更新最新活动截止时间
}
}
printf("%d", Ret[0]);
for (int i = 1; i < pos; i++) printf(",%d", Ret[i]); //结果格式处理
printf("\n");
return 0;
}
bool cmp(struct Activity a, struct Activity b) {
return a.rear < b.rear;
}
/***************************************************
User name: SupremeBeast
Result: Accepted
Take time: 0ms
Take Memory: 196KB
Submit time: 2019-04-27 10:54:09
****************************************************/