题目:
一天中,要进行N个面试,它们的时间分别为[B[i], E[i]],分别表示面试的开始时间跟面试的结束时间。这N个面试安排在若干个面试点进行,不同的面试在同一个时间不能被安排在同一个面试点。
现在要求出至少需要多少个面试点。
分析思路:
通过贪心算法来解决,算法的思路是:对于所有的面试I[i] = [B[i], E[i]],按B[i]从小到大排序,然后按顺序对各个区间着色。
对当前区间i着色时,必须保证所着的颜色(color[i])没有被出现在这个区域之前且时间段与当前区间有重叠的区间用到。
假设面试的总数为N,那么代码如下:
int nMaxColor = 0, k = 0;
bool isForbidden[NMAX];
for(int i = 0; i < n; ++i) {
for(k = 0; k < nMaxColor; ++k) isForbidden[k] = false;
for(int j = 0; j < i; ++j) if(Overlap(b[j], e[j], b[i], e[i])) isForbidden[color[j]] = true;
for(k = 0; k < nMaxColor; ++k) if(!isForbidden[k]) break;
if(k < nMaxColor) color[i] = k;
else color[i] = nMaxColor++;
}
上述代码中nMaxColor就是最后返回的所需的最少颜色。
isForbidden是对于每个时间区间i,其他时间区间j中开始时间位于这个时间区间之前的且与这个时间区间有重叠的面试所占用的颜色的标识数组。
Overlap函数,则是用来判断两个时间区间是否有重叠。
还有一种更简单的思路:
我们要得到的是最少所需的颜色数
仍然先对面试数组排序, 然后遍历面试数组, 每遇到一个 B, color +1, 并维护全局最大 color 数; 每遇到一个 E, color 数减一. 返回全局最大 color 值
代码如下:
int nColorUsing = 0, nMaxColor = 0;
for(int i = 0; i < 2 * n; ++i) {
if(TimePoints[i].type == "Begin") {
nColorUsing++;
if(nColorUsing > nMaxColor) nMaxColor = nColorUsing;
}else nColorUsing--;
}