1.9 高效率的安排见面会
1.9 高效率的安排见面会
基本问题:在校园招聘的季节里,为了能让学生们更好地了解微软亚洲研究院各研究组的情况,HR部门计划为每一个研究组举办一次见面会,让各个研究组的员工能跟学生相互了解和交流。已知有n位学生,他们分别对m个研究组中的若干个感兴趣。为了满足所有学生的要求,HR希望每个学生都能参加自己感兴趣的所有见面会。如果每个见面会的时间为t,那么,如何安排才能够使得所有见面会的总时间最短? 最简单的办法,就是把m个研究组的见面会时间依次排开,那我们就要用m * t的总时间,我们有10多个研究小组,时间会拖得很长,能否进一步提高效率?
解法:将问题转化为图的模型进行,将每场招聘会假想成一个图中的节点,有学生同时参加两个招聘会,就将两个节点相连,最终得到一个完整的图,那么不想连的图肯定是可以同时举办的,也就节省了总的时间。如何求出这些不相连的节点呢,这就需要再一次转化,将求不直接相连节点问题转化为求图的最少着色问题,显然,同一种颜色的节点肯定是不想连的。这就转化成了图的最少着色问题。即图的最少着色问题
拓展问题
拓展问题1
- 面试的时候,每次会面都有一个开始时间b[i] 和 结束时间e[i] 。
- 现在有一组面试时间数据,现在要求每一个有冲突的时间,都不允许安排在同一个地点,求出最小需要安排的地点数目。
解法:
- 解法1:也可以通过染色问题解决
- 解法2:区间合并问题
拓展问题2 让每一个同学感兴趣的见面会尽可能的集中
解法:同学对见面会的兴趣度可以理解为图中的边的权重,让每个都集中也就是总体集中顶点着色数量设计好后,顶点起始时间排序,起始时间相同则按照上一顶点与欲选择顶点的兴趣度排序,最后得到结果
All Coding
// 1.9 高效率的安排见面会
import java.util.*;
class Test{
static List<List<Integer>> graph;
static int[] colored;
public static void main(String[] args) {
/**
基础问题:在校园招聘的季节里,为了能让学生们更好地了解微软亚洲研究院各研究组的情况,HR部门计划为每一个研究组举办一次见面会,让各个研究组的员工能跟学生相互了解和交流(如图1-4所示)。已知有n位学生,他们分别对m个研究组中的若干个感兴趣。为了满足所有学生的要求,HR希望每个学生都能参加自己感兴趣的所有见面会。如果每个见面会的时间为t,那么,如何安排才能够使得所有见面会的总时间最短? 最简单的办法,就是把m个研究组的见面会时间依次排开,那我们就要用m * t的总时间,我们有10多个研究小组,时间会拖得很长,能否进一步提高效率?
> 解法:
将问题转化为图的模型进行,将每场招聘会假想成一个图中的节点,有学生同时参加两个招聘会,就将两个节点相连,最终得到一个完整的图,那么不想连的图肯定是可以同时举办的,也就节省了总的时间。如何求出这些不相连的节点呢,这就需要再一次转化,将求不直接相连节点问题转化为求图的最少着色问题,显然,同一种颜色的节点肯定是不想连的。这就转化成了图的最少着色问题。
即图的最少着色问题
*/
int n= 3;
int[][] paths = new int[][]{{1,2},{2,3},{3,1}};
System.out.println(minColors(n,paths).length);
int[][] intervals = {{1,3},{2,6},{8,10},{15,18},{22,24}};
System.out.println(merge(intervals).length);
}
public static int[] minColors(int n, int[][] paths) {
graph = new LinkedList<List<Integer>>();
colored = new int[n+1];
for(int i = 0;i<n+1;i++) graph.add(new LinkedList<Integer>());
for(int[] info:paths){
graph.get(info[0]).add(info[1]);
graph.get(info[1]).add(info[0]);
}
for(int i = 1;i<n+1;i++) dfs(i);
int[] res = new int[n];
for(int i = 0;i < n;i++) res[i] = colored[i+1];
return res;
}
public static void dfs(int n){
if(colored[n] != 0) return;
int[] record = new int[5];
for(int node:graph.get(n)) record[colored[node]]=1;
for(int i = 0;i<record.length;i++) if(record[i]==0) colored[n]=i;
for(int node:graph.get(n)){
dfs(node);
}
}
/**
拓展问题:
拓展问题1:(1) 面试的时候,每次会面都有一个开始时间b[i] 和 结束时间e[i] 。
(2) 现在有一组面试时间数据,现在要求每一个有冲突的时间,都不允许安排在同一个地点,求出最小需要安排的地点数目。
> 解法
解法1:也可以通过染色问题解决
解法2:区间合并问题
拓展问题2:让每一个同学感兴趣的见面会尽可能的集中
解法:同学对见面会的兴趣度可以理解为图中的边的权重,让每个都集中也就是总体集中顶点着色数量设计好后,顶点起始时间排序,起始时间相同则按照上一顶点与欲选择顶点的兴趣度排序,最后得到结果
*/
/**
拓展问题1:就是典型的合并区间问题
*/
public static int[][] merge(int[][] intervals) {
if (intervals.length == 0) {
return new int[0][2];
}
Arrays.sort(intervals,(o1,o2)->(o1[0] - o2[0]));
List<int[]> merged = new ArrayList<int[]>();
for (int i = 0; i < intervals.length; ++i) {
int L = intervals[i][0], R = intervals[i][1];
if (merged.size() == 0 || merged.get(merged.size() - 1)[1] < L) {
merged.add(new int[]{L, R});
} else {
merged.get(merged.size() - 1)[1] = Math.max(merged.get(merged.size() - 1)[1], R);
}
}
return merged.toArray(new int[merged.size()][]);
}
/**
拓展问题2:
同学对见面会的兴趣度可以理解为图中的边的权重,让每个都集中也就是总体集中顶点着色数量设计好后,顶点起始时间排序,起始时间相同则按照上一顶点与欲选择顶点的兴趣度排序,最后得到结果
*/
}
Saying Less Doing More