一.区间调度问题
有n项工作,每项工作分别在start[i]时间开始,在End(i)时间结束。对于每项工作,你都可以选择参与与否,如果选择参与,那么自始至终必须全程参与。此外参与时间段不能重叠(即使是开始的瞬间与结束的瞬间重叠也是不允许的),那么最多能参与多少项工作?
二.解法
//算法思想:在可选的工作中,每次都选取结束时间最早的工作
#include <iostream>
#include <utility>
#include <algorithm>
using namespace std;
//设置全局变量
const int MAX = 10000;
int N = 5;//工作的个数
int Start[MAX] = {1, 2, 4, 6, 8};//存储开始时间的数组
int End[MAX] = {3, 5, 7, 9, 10};//存储结束时间的数组
pair<int, int> space[MAX];
//选取最多工作的个数
void Solve()
{
int count = 0;//存储工作个数
int t = 0;//存储结束时间
for(int i = 0; i < N; ++i)
{
space[i].first = End[i];//第一个数据成员存储结束时间
space[i].second = Start[i];//第二个数据成员存储开始时间
}
//对结束时间按字典排序
sort(space, space + 5);
for(int j = 0; j < N; ++j)
{
if(t < space[j].second)//判断是否重叠
{
++count;
t = space[j].first;//每次给t赋结束时间
}
}
cout << count;
}
int main()
{
Solve();
return 0;
}
在可选的工作中,我们可以选择
(1)开始时间最早的,存在反例
(2)结束时间最早的
(3)用时最短的,反例
(4)与最少可选工作有重叠的,反例
直观解释,结束时间越早,后面可选的工作也越多.
证明方法(1)与其他方案相比,该算法选择了相同数量的更早开始的工作,其最终结束时间不会比其它方案的更晚。
(2)所以不存在选取更多工作的选择方案