当前位置:  首页>> 技术小册>> 数据结构与算法(中)

难度:
Hard

题意:

  1. n个工人,有一个工作量数组quality,有个最低工资数组wage
  2. 要聘用K个工人,工资最低。要求,这n个工人的工资必须不低于他们的最低工资要求,并且他们的工资跟工作量成正比

思路:

  • 由于工资跟工作量成正比,假设这个比率是r。第i工人愿意被聘用的条件是r>=wage[i]/quality[i]
  • 令ratio[i]=wage[i]/quality[i],对ratio[i]排序,遍历数组ratio,i每递曾一个,就有一个工人愿意被聘用
  • 假设现在有p个工人愿意被聘用(p>=K),现在轮到我们来挑选K个人,由于工资总和要最低,且工资=工作量*p,所以在这p个人中挑选工作量最低的K个人
  • 子问题是,求数列中前K小的数,需要最小堆
  • 复杂度是o(nlogn)

代码:

  1. class Solution {
  2. public double mincostToHireWorkers(int[] quality, int[] wage, int K) {
  3. double[] ratio = new double[quality.length];
  4. Integer[] pos = new Integer[quality.length];
  5. for (int i = 0;i < quality.length;i++) {
  6. ratio[i] = (double) wage[i] / quality[i];
  7. pos[i] = i;
  8. }
  9. Arrays.sort(pos, new Comparator<Integer>() {
  10. @Override
  11. public int compare(Integer o1, Integer o2) {
  12. return Double.compare(ratio[o1], ratio[o2]);
  13. }
  14. });
  15. double ret = 1e40;
  16. int maxK = 0;
  17. PriorityQueue<Integer> queue = new PriorityQueue<Integer>(new Comparator<Integer>() {
  18. @Override
  19. public int compare(Integer o1, Integer o2) {
  20. return -Integer.compare(o1, o2);
  21. }
  22. });
  23. for (int i = 0;i < pos.length;i++) {
  24. maxK += quality[pos[i]];
  25. queue.add(quality[pos[i]]);
  26. if (queue.size() > K) {
  27. maxK -= queue.poll();
  28. }
  29. if (queue.size() == K) {
  30. ret = ret > maxK * ratio[pos[i]] ? maxK * ratio[pos[i]] : ret;
  31. }
  32. }
  33. return ret;
  34. }
  35. }

该分类下的相关小册推荐: