贪心算法典型例题
贪心算法通常时间复杂度同
(i)单线程问题:活动安排问题、背包问题、最优装载问题
(ii)多线程问题:服务器问题
1宣讲会安排问题
已知宣讲会的起始与结束时间点,要求有限时间内尽可能多的安排宣讲会的数量。
1.1求解思路:
考虑贪心算法,我们想如果:
①每次都挑开始最早的项目进行安排; (×)
②每次都选持续时间最短的项目进行安排;(×)
③每次选择结束时间最早的项目进行安排;(√)
1.2算法实现流程
1)用两个数组分别存储项目对应的开始时间和结束时间,此时存入的时间是无序的,但是数组下标对应的是同一个项目。
2)将一个结束时间最早的项目作为第一个进场,其后遍历数组,找到下一个开始时间最接近的项目(这个项目必须同时是结束时间排序中最早的)。
3)将项目的标号进行打印,得到最优项目安排。
备注:用比较器对项目进行排序;
用结构体封装时间信息方便排序;
1.3程序清单
#include <iostream>
#include <algorithm>
using namespace std;
#define N 11
void gerrdy_activity_selector(int *start, int *end, int *ret);
int find_ternnum(int* start, int* end, int m);
struct time {
int s;
int e;
};
time act[100];
int main() {
//这里按照项目的输入顺序来存储,下标为t 就是项目t。
int start[N + 1] = {
-1, 12, 3, 0, 3, 5, 5, 6, 8, 8, 2, 1 };
int end[N + 1] = {
-1, 14, 5, 6, 8, 9, 7, 10, 11, 12, 13, 4 };
int ret[N] = {
0 };
//将数组存储到结构体中是为了排序的时候打包排序
for (int i = 0; i <= N; i++) {
act[i].s = start[i];
act[i].e = end[i];
}
gerrdy_activity_selector(start, end, ret);
printf("最大子集为:");
for (int i = 0; i < N; i++) {
if (ret[i] != 0) {
cout << "a" << ret[i] << "->";
}
}
cout << "end" << endl;
system("pause");
return 0;
}
//比较器
bool cmp(time a, time b) {
return a.e < b.e;
}
void gerrdy_activity_selector(int *start, int *end, int *ret) {