一个面试题的思考

来源:互联网 发布:sql server 2012 下载 编辑:程序博客网 时间:2024/05/22 16:31
现在有n位工程师和6项工作(编号为0至5),现在给出每个人能够胜任的工作序号表
 (用一个字符串表示,比如:045,表示某位工程师能够胜任0号,4号,5号工作
 )。现在需要进行工作安排,每位工程师只能被安排到自己能够胜任的工作当中去,两位工程师不能安排到同一项工作当中去。
 如果两种工作安排中有一个人被安排在的工作序号不一样就被视为不同的工作安排,现在需要计算出有多少种不同工作安排计划。
 
 输入描述:
 
 输入数据有n+1行: 第一行为工程师人数n(1 ≤ n ≤ 6) 接下来的n行,每行一个字符串表示第i(1 ≤ i ≤
 n)个人能够胜任的工作(字符串不一定等长的)
 
 输出描述:
 
 输出一个整数,表示有多少种不同的工作安排方案
 
 输入例子:
 
 6 012345 012345 012345 012345 012345 012345
 
 输出例子:
 

  720


基本要求:


基础假设:
工作,人可以任意分配,在可以分配时,不能不分配,

工作数>=人数
求可能的分配方案数
方案数=
人1工作1*剩余方案+人1工作2*剩余方案+。。。。+人1工作n*剩余方案
剩余方案:剩余人选剩余工作个数=人1工作1*剩余方案+人1工作2*剩余方案+。。。。+人1工作n*剩余方案
如果剩余的人=0,返回1,
如果剩余工作=0,返回1


代码如下:

public int simplePersonWork(List<String> personList, List<String> workList) {int count = 0;String works = "workList=" + workList;//如果工作数或者人数剩余1个,那么方案总数=personList.size() * workList.size()if (personList.size() == 1 || workList.size() == 1) {count = personList.size() * workList.size();System.out.println(works + " personList=" + personList + " count=" + count);return count;}//循环工作,人1分配工作ifor (int i = 0; i < workList.size(); i++) {List<String> subWorkList = new ArrayList<String>();subWorkList.addAll(workList);subWorkList.remove(i);//人1*剩余的方案数//剩余的人=1以后的人//,剩余的工作=workList删除当前workcount = count + simplePersonWork(personList.subList(1, personList.size()), subWorkList);}System.out.println(works + " personList=" + personList + " count=" + count);return count;}



修改要求如下:

每个人都有不同的技能,每个工作需要的技能不一样,每个人只能分配到他会的技能上,每个人都必须分配

方案如下:

思路和上面类似:在对匹配人和工作时,加上技能释放合适

这种对,人技能有要求,必须可以完全分配,不能出现大家都只会一个工作的情况


public int personWork(List<String> personList, List<String> workList) {int count = 0;String works = "workList=" + workList;// 返回人可以匹配的工作个数if (personList.size() == 1) {String person = personList.get(0);for (String work : workList) {if (person.contains(work)) {count++;}}System.out.println(works + " personList=" + personList + " count=" + count);return count;}// 循环工作,人1分配工作ifor (int i = 0; i < workList.size(); i++) {List<String> subWorkList = new ArrayList<String>();subWorkList.addAll(workList);String person = personList.get(0);// 获取第j个人if (person.contains(workList.get(i))) {// 如果当前人员技能可以做当前工作subWorkList.remove(i);// 人1*剩余的方案数// 剩余的人=1以后的人// ,剩余的工作=workList删除当前workint subcount = personWork(personList.subList(1, personList.size()), subWorkList);count = count + subcount;}}System.out.println(works + " personList=" + personList + " count=" + count);return count;}



在添加要求:

每个人都有不同的技能,每个工作需要的技能不一样,每个人只能分配到他会的技能上,

如果可能的情况下,必须分配工作,但是允许如果没有可分配的工作时,不分配工作,

这种情况下,人员的技能没有要求,多人技能可能会重复导致没有工作可分配,需要考虑


方案总数如下:

方案总数=人1分配工作数*剩余方案数+人1不分配工作数*剩余方案数

人1分配工作时,计算方式和上面的计算逻辑一样
人1不分配工作时,要求剩下的人最后分配剩余的工作,人员不适合(和要求中的可分配工作时,必须分配)



代码逻辑如下:


/** *  * @param personList人员集合,每个string为人员技能 * @param workList *            工作集合,每个集合的编号 * @param first *            表示第一个人,用于判断剩余的工作,第一个人是否可以做,如果不能做,那么这就是一种方案,否则不是一种新的方案 *  * @return */public int personWorkSenior(List<String> personList, List<String> workList, String first) {int count = 0;String works = "workList=" + workList;// 返回人可以匹配的工作个数if (personList.size() == 1) {String tempwork = null;int tempcount = 0;if (first != null) {/// 第一个人不分配工作for (String work : workList) {if (first.contains(work)) {tempwork = work;tempcount++;if (tempcount >= 2) {return 0;// 这里如果有2个适合第一个人,// 那么剩余的工作中肯定有一个可以分给第一个人,方案已存在,返回0}}if (tempwork != null) {// tempwork不为空,tempcount=1,只有一个合适第一个人的,如果也合适最后一个人,那么分配给最后一个人,也是一种方案,if (personList.get(0).contains(tempwork)) {return 1;}}}}// 下面计算最后一个人,可以分配的工作数String person = personList.get(0);for (String work : workList) {if (person.contains(work)) {count++;}}System.out.println(works + " personList=" + personList + " first=" + first + " count=" + count);return count;}// 循环工作,人1分配工作ifor (int i = 0; i < workList.size(); i++) {List<String> subWorkList = new ArrayList<String>();subWorkList.addAll(workList);String person = personList.get(0);// 获取第j个人if (person.contains(workList.get(i))) {// 如果当前人员技能可以做当前工作subWorkList.remove(i);// 人1*剩余的方案数// 剩余的人=1以后的人// ,剩余的工作=workList删除当前workint subcount = personWorkSenior(personList.subList(1, personList.size()), subWorkList, null);if (subcount > 0) {count = count + subcount;} else {count++;// 因为这里已经给人1分配了工作,所以剩余的方案没有时,这也是一种方案}}}// 下面计算,去掉第一个人,的结算结果count = count + personWorkSenior(personList.subList(1, personList.size()), workList, personList.get(0));System.out.println(works + " personList=" + personList + " count=" + count);return count;}


0 0
原创粉丝点击