JavaInterview JavaInterview
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)

『Java面试+Java学习』
首页
指南
分类
标签
归档
  • CSDN (opens new window)
  • 文档集合 (opens new window)
  • 系统架构 (opens new window)
  • 微信号 (opens new window)
  • 公众号 (opens new window)
  • 指南
  • 简历

  • Java

  • 面试

  • 算法

  • algorithm
  • leetcode
JavaInterview.cn
2024-03-24
目录

雇佣 K 名工人的最低成本Java

文章发布较早,内容可能过时,阅读注意甄别。

# 题目

有 n 名工人。 给定两个数组 quality 和 wage ,其中,quality[i] 表示第 i 名工人的工作质量,其最低期望工资为 wage[i] 。

现在我们想雇佣 k 名工人组成一个工资组。在雇佣 一组 k 名工人时,我们必须按照下述规则向他们支付工资:

  • 对工资组中的每名工人,应当按其工作质量与同组其他工人的工作质量的比例来支付工资。
  • 工资组中的每名工人至少应当得到他们的最低期望工资。 给定整数 k ,返回 组成满足上述条件的付费群体所需的最小金额 。在实际答案的 10-5 以内的答案将被接受。。

示例 1:

  • 输入: quality = [10,20,5], wage = [70,50,30], k = 2

  • 输出: 105.00000

  • 解释: 我们向 0 号工人支付 70,向 2 号工人支付 35。 示例 2:

  • 输入: quality = [3,1,10,10,1], wage = [4,8,2,2,7], k = 3

  • 输出: 30.66667

  • 解释: 我们向 0 号工人支付 4,向 2 号和 3 号分别支付 13.33333。

提示:

  • n == quality.length == wage.length
  • 1 <= k <= n <= 104
  • 1 <= quality[i], wage[i] <= 104

# 思路

优先队列

# 解法


class Solution {
    public double mincostToHireWorkers(int[] quality, int[] wage, int k) {
        int n = quality.length;
        // 用一个数组保存每名工人的情况,记录性价比。
        double[][] workers = new double[n][2];
        for (int i = 0; i < n; i++)
            workers[i] = new double[] {(double) wage[i] / quality[i], (double) quality[i]};
        // 注意保存的是预期工资和工作质量的比,越小性价比越高,
        // 按照第一个关键字升序排序。
        Arrays.sort(workers, (x, y) -> Double.compare(x[0], y[0]));
        double res = Double.MAX_VALUE;
        // 保存当前选中工人的工作质量总和。
        double sum = 0.0F;
        // 大顶堆保存当前选中的 k 个人的工作质量情况。
        PriorityQueue<Double> heap = new PriorityQueue<>((x, y) -> Double.compare(y, x));
        // 当前遍历到的是目前性价比最低的。
        for (double[] worker : workers) {
            // 如何计算 k 个人需要的最小工资?这样考虑,假设有三
            // 个工人 x1, x2, x3...,他们的质量是 q(x1),q(x2), 
            // q(x3)...,期望是 e(x1), e(x2), e(x3)...,实际分
            // 配的为 f(x1), f(x2), f(x3)..,有 q(x1)/f(x1) = 
            // q(x2)/f(x2) = q(x3)/f(x3) = ... = c,则对于所有
            // 的 xk,有 q(x)/c = f(x) >= e(x),...,即 
            // q(x)/e(x) >= c,则要满足所有这样的,则要优先满足
            // q(x)/e(x) 最小的,即满足性价比最低的,也就是当前
            // 的 worker[0],那么 worker[0] * sum 就可以满足所
            // 有的工人的最低需求了。
            if (heap.size() == k)
                // 如果当前已经安排了 k 个人,肯定先去掉质量最大
                // 的工人,来尽可能降低总质量(worker[0] * sum 
                // 是最低工资,既然 worker[0] 是定死的,那么想办
                // 法降低 sum,移除最大的)。
                sum -= heap.poll();
            // 先将当前性价比最低的工人加入。
            sum += worker[1];
            heap.offer(worker[1]);
            if (heap.size() == k)
                res = Math.min(res, sum * worker[0]);
        }
        return res;
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

# 总结

  • 分析出几种情况,然后分别对各个情况实现
微信 支付宝
最近更新
01
1686. 石子游戏VI Java
08-18
02
1688. 比赛中的配对次数 Java
08-18
03
1687. 从仓库到码头运输箱子 Java
08-18
更多文章>
Theme by Vdoing | Copyright © 2019-2025 JavaInterview.cn
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式