Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6ec7fbd

Browse files
Merge pull request SharingSource#672 from SharingSource/ac_oier
✨feat: add 857
2 parents 890b113 + bf49410 commit 6ec7fbd

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

‎Index/堆.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
| [726. 原子的数量](https://leetcode-cn.com/problems/number-of-atoms/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/number-of-atoms/solution/gong-shui-san-xie-shi-yong-xiao-ji-qiao-l5ak4/) | 困难 | 🤩🤩🤩🤩 |
1818
| [786. 第 K 个最小的素数分数](https://leetcode-cn.com/problems/k-th-smallest-prime-fraction/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/k-th-smallest-prime-fraction/solution/gong-shui-san-xie-yi-ti-shuang-jie-you-x-8ymk/) | 中等 | 🤩🤩🤩 |
1919
| [846. 一手顺子](https://leetcode-cn.com/problems/hand-of-straights/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/hand-of-straights/solution/gong-shui-san-xie-shu-ju-jie-gou-mo-ni-t-4hxw/) | 中等 | 🤩🤩🤩 |
20+
| [857. 雇佣 K 名工人的最低成本](https://leetcode.cn/problems/minimum-cost-to-hire-k-workers/) | [LeetCode 题解链接](https://leetcode.cn/problems/minimum-cost-to-hire-k-workers/solution/by-ac_oier-u42f/) | 困难 | 🤩🤩🤩🤩🤩 |
2021
| [871. 最低加油次数](https://leetcode.cn/problems/minimum-number-of-refueling-stops/) | [LeetCode 题解链接](https://leetcode.cn/problems/minimum-number-of-refueling-stops/solution/by-ac_oier-q2mk/) | 困难 | 🤩🤩🤩🤩🤩 |
2122
| [954. 二倍数对数组](https://leetcode-cn.com/problems/array-of-doubled-pairs/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/array-of-doubled-pairs/solution/by-ac_oier-d1z7/) | 中等 | 🤩🤩🤩🤩 |
2223
| [987. 二叉树的垂序遍历](https://leetcode-cn.com/problems/vertical-order-traversal-of-a-binary-tree/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/vertical-order-traversal-of-a-binary-tree/solution/gong-shui-san-xie-yi-ti-shuang-jie-dfs-h-wfm3/) | 困难 | 🤩🤩🤩🤩🤩 |
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[857. 雇佣 K 名工人的最低成本](https://leetcode.cn/problems/minimum-cost-to-hire-k-workers/solution/by-ac_oier-u42f/)** ,难度为 **困难**
4+
5+
Tag : 「枚举」、「优先队列(堆)」
6+
7+
8+
9+
`n` 名工人。 给定两个数组 `quality``wage` ,其中,`quality[i]` 表示第 `i` 名工人的工作质量,其最低期望工资为 `wage[i]`
10+
11+
现在我们想雇佣 `k` 名工人组成一个工资组。在雇佣 一组 `k` 名工人时,我们必须按照下述规则向他们支付工资:
12+
13+
* 对工资组中的每名工人,应当按其工作质量与同组其他工人的工作质量的比例来支付工资。
14+
* 工资组中的每名工人至少应当得到他们的最低期望工资。
15+
16+
给定整数 `k`,返回 组成满足上述条件的付费群体所需的最小金额 。在实际答案的 10ドル^{-5}$ 以内的答案将被接受。。
17+
18+
示例 1:
19+
```
20+
输入: quality = [10,20,5], wage = [70,50,30], k = 2
21+
22+
输出: 105.00000
23+
24+
解释: 我们向 0 号工人支付 70,向 2 号工人支付 35。
25+
```
26+
示例 2:
27+
```
28+
输入: quality = [3,1,10,10,1], wage = [4,8,2,2,7], k = 3
29+
30+
输出: 30.66667
31+
32+
解释: 我们向 0 号工人支付 4,向 2 号和 3 号分别支付 13.33333。
33+
```
34+
35+
提示:
36+
* $n = quality.length = wage.length$
37+
* 1ドル <= k <= n <= 10^4$
38+
* 1ドル <= quality[i], wage[i] <= 10^4$
39+
40+
---
41+
42+
### 枚举 + 优先队列(堆)
43+
44+
为了方便,我们令 `quality``qs`,`wage``ws`
45+
46+
从 $n$ 个工人中选 $k$ 个,使这 $k$ 个工人实际工资与其 $qs[i]$ 成比例,且实际工资不低于 $ws[i]$。
47+
48+
根据条件一,假设实际工资与能力值比值为 $t,ドル则所选工人的实际工资为 $qs[i] \times t,ドル再结合条件二可知 $qs[i] \times t >= ws[i],ドル变形可得 $t >= \frac{ws[i]}{qs[i]}$。
49+
50+
那么在选定若干工人的情况下,为使得总支出最小,我们可以取 $t$ 为所有被选工人中的最大 $\frac{ws[i]}{qs[i]}$ 即可。
51+
52+
**因此最终的 $t$ 值必然是取自某个工人的实际比值 $\frac{ws[i]}{qs[i]},ドル这引导我们可以通过「枚举」哪个工人的实际比值为实际 $t$ 值来做。**
53+
54+
假设我们已经预处理出所有工人的 $\frac{ws[i]}{qs[i]}$ 比值信息,并「从小到大」进行枚举(该过程可看做是以比值信息作为维度来枚举每个工人):假设当前处理到的比值为最终使用到的 $t,ドル我们能够选的工人必然是在该工人的左边(根据上述分析可知,被选的工人满足 $\frac{ws[i]}{qs[i]} <= t$ 条件)。
55+
56+
因此,我们可以使用二维数组 `ds` 记录下每个工人的 $\frac{ws[i]}{qs[i]}$ 比值信息:$ds[i][0] = \frac{ws[i]}{qs[i]},ドル$ds[i][1] = i$。并对其进行排升序,枚举每个工人的实际比值,同时动态维护枚举过程中的最小 $k$ 个 $qs[i]$(使用「大根堆」处理),并使用单变量 `tot` 记录当前堆中的 $qs[i]$ 总和,$tot \times \frac{ws[i]}{qs[i]}$ 即是以当前比值作为实际 $t$ 值时的总成本,在所有总成本中取最小值即是答案。
57+
58+
Java 代码:
59+
```Java
60+
class Solution {
61+
public double mincostToHireWorkers(int[] qs, int[] ws, int k) {
62+
int n = qs.length;
63+
double[][] ds = new double[n][2];
64+
for (int i = 0; i < n; i++) {
65+
ds[i][0] = ws[i] * 1.0 / qs[i]; ds[i][1] = i * 1.0;
66+
}
67+
Arrays.sort(ds, (a,b)->Double.compare(a[0], b[0]));
68+
PriorityQueue<Integer> q = new PriorityQueue<>((a,b)->b-a);
69+
double ans = 1e18;
70+
for (int i = 0, tot = 0; i < n; i++) {
71+
int cur = qs[(int)ds[i][1]];
72+
tot += cur; q.add(cur);
73+
if (q.size() > k) tot -= q.poll();
74+
if (q.size() == k) ans = Math.min(ans, tot * ds[i][0]);
75+
}
76+
return ans;
77+
}
78+
}
79+
```
80+
TypeScript 代码:
81+
```TypeScript
82+
function mincostToHireWorkers(qs: number[], ws: number[], k: number): number {
83+
const n = qs.length
84+
const ds: number[][] = new Array<Array<number>>()
85+
for (let i = 0; i < n; i++) ds.push([ws[i] / qs[i], i])
86+
ds.sort((a,b)=>a[0]-b[0])
87+
const q = new MaxPriorityQueue()
88+
let ans = 1e18
89+
for (let i = 0, tot = 0; i < n; i++) {
90+
const cur = qs[ds[i][1]]
91+
tot += cur
92+
q.enqueue(cur)
93+
if (q.size() > k) tot -= q.dequeue().element
94+
if (q.size() == k) ans = Math.min(ans, tot * ds[i][0])
95+
}
96+
return ans
97+
};
98+
```
99+
* 时间复杂度:构造系数并排序复杂度为 $O(n\log{n})$;枚举并计算答案复杂度为 $O(n\log{k})$。整体复杂度为 $O(n\log{n})$
100+
* 空间复杂度:$O(n)$
101+
102+
---
103+
104+
### 最后
105+
106+
这是我们「刷穿 LeetCode」系列文章的第 `No.857` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
107+
108+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
109+
110+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
111+
112+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
113+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /