Skip to content

Commit 50649c7

Browse files
committed
feat: add solutions to lc problem: No.0857
No.0857.Minimum Cost to Hire K Workers
1 parent 582773d commit 50649c7

File tree

7 files changed

+351
-33
lines changed

7 files changed

+351
-33
lines changed

solution/0800-0899/0857.Minimum Cost to Hire K Workers/README.md

Lines changed: 129 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,150 @@
5050

5151
<!-- 这里可写通用的实现逻辑 -->
5252

53+
**方法一:贪心 + 优先队列(大根堆)**
54+
55+
我们假设选取了某一个工资组,总工作质量为 `tot`,总支付金额为 `c`。每个工人的工作质量为 $q_i$,工资为 $w_i$。那么,对于此工资组的每个工人,均满足 $c\times \frac{q_i}{tot} \ge w_i$。即 $c\ge tot\times \frac{w_i}{q_i}$。
56+
57+
在总工作质量 `tot` 固定的情况下,支付的金额取决于权重 $\frac{w_i}{q_i}$ 的最大值。
58+
59+
我们可以从小到大枚举权重 $\frac{w_i}{q_i}$ 作为工资组的最大值,此时工资组其他人员只需要在权重小于等于这个值的集合中,选取工作质量最小的 $k-1$ 名工人来组成工资组即可。因此,可以用优先队列(最大堆)维护工作质量最小的 $k-1$ 名工人。
60+
61+
时间复杂度 $O(n\log n)$,空间复杂度 $O(n)$。其中 $n$ 是工人数。
62+
5363
<!-- tabs:start -->
5464

5565
### **Python3**
5666

5767
<!-- 这里可写当前语言的特殊实现逻辑 -->
5868

5969
```python
60-
70+
class Solution:
71+
def mincostToHireWorkers(self, quality: List[int], wage: List[int], k: int) -> float:
72+
t = sorted(zip(quality, wage), key=lambda x: x[1] / x[0])
73+
ans, tot = inf, 0
74+
h = []
75+
for q, w in t:
76+
tot += q
77+
heappush(h, -q)
78+
if len(h) == k:
79+
ans = min(ans, w / q * tot)
80+
tot += heappop(h)
81+
return ans
6182
```
6283

6384
### **Java**
6485

6586
<!-- 这里可写当前语言的特殊实现逻辑 -->
6687

6788
```java
89+
class Solution {
90+
public double mincostToHireWorkers(int[] quality, int[] wage, int k) {
91+
int n = quality.length;
92+
Pair[] t = new Pair[n];
93+
for (int i = 0; i < n; ++i) {
94+
t[i] = new Pair(quality[i], wage[i]);
95+
}
96+
Arrays.sort(t, (a, b) -> Double.compare(a.x, b.x));
97+
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
98+
double ans = 1e9;
99+
int tot = 0;
100+
for (var e : t) {
101+
tot += e.q;
102+
pq.offer(e.q);
103+
if (pq.size() == k) {
104+
ans = Math.min(ans, tot * e.x);
105+
tot -= pq.poll();
106+
}
107+
}
108+
return ans;
109+
}
110+
}
111+
112+
class Pair {
113+
double x;
114+
int q;
115+
116+
Pair(int q, int w) {
117+
this.q = q;
118+
this.x = (double) w / q;
119+
}
120+
}
121+
```
122+
123+
### **C++**
124+
125+
```cpp
126+
class Solution {
127+
public:
128+
double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int k) {
129+
int n = quality.size();
130+
vector<pair<double, int>> t(n);
131+
for (int i = 0; i < n; ++i) {
132+
t[i] = {(double) wage[i] / quality[i], quality[i]};
133+
}
134+
sort(t.begin(), t.end());
135+
priority_queue<int> pq;
136+
double ans = 1e9;
137+
int tot = 0;
138+
for (auto& [x, q] : t) {
139+
tot += q;
140+
pq.push(q);
141+
if (pq.size() == k) {
142+
ans = min(ans, tot * x);
143+
tot -= pq.top();
144+
pq.pop();
145+
}
146+
}
147+
return ans;
148+
}
149+
};
150+
```
68151
152+
### **Go**
153+
154+
```go
155+
func mincostToHireWorkers(quality []int, wage []int, k int) float64 {
156+
t := []pair{}
157+
for i, q := range quality {
158+
t = append(t, pair{float64(wage[i]) / float64(q), q})
159+
}
160+
sort.Slice(t, func(i, j int) bool { return t[i].x < t[j].x })
161+
tot := 0
162+
var ans float64 = 1e9
163+
pq := hp{}
164+
for _, e := range t {
165+
tot += e.q
166+
heap.Push(&pq, e.q)
167+
if pq.Len() == k {
168+
ans = min(ans, float64(tot)*e.x)
169+
tot -= heap.Pop(&pq).(int)
170+
}
171+
}
172+
return ans
173+
}
174+
175+
func min(a, b float64) float64 {
176+
if a < b {
177+
return a
178+
}
179+
return b
180+
}
181+
182+
type pair struct {
183+
x float64
184+
q int
185+
}
186+
187+
type hp struct{ sort.IntSlice }
188+
189+
func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
190+
func (h *hp) Pop() interface{} {
191+
a := h.IntSlice
192+
v := a[len(a)-1]
193+
h.IntSlice = a[:len(a)-1]
194+
return v
195+
}
196+
func (h *hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] }
69197
```
70198

71199
### **...**

solution/0800-0899/0857.Minimum Cost to Hire K Workers/README_EN.md

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,131 @@
4848
### **Python3**
4949

5050
```python
51-
51+
class Solution:
52+
def mincostToHireWorkers(self, quality: List[int], wage: List[int], k: int) -> float:
53+
t = sorted(zip(quality, wage), key=lambda x: x[1] / x[0])
54+
ans, tot = inf, 0
55+
h = []
56+
for q, w in t:
57+
tot += q
58+
heappush(h, -q)
59+
if len(h) == k:
60+
ans = min(ans, w / q * tot)
61+
tot += heappop(h)
62+
return ans
5263
```
5364

5465
### **Java**
5566

5667
```java
68+
class Solution {
69+
public double mincostToHireWorkers(int[] quality, int[] wage, int k) {
70+
int n = quality.length;
71+
Pair[] t = new Pair[n];
72+
for (int i = 0; i < n; ++i) {
73+
t[i] = new Pair(quality[i], wage[i]);
74+
}
75+
Arrays.sort(t, (a, b) -> Double.compare(a.x, b.x));
76+
PriorityQueue<Integer> pq = new PriorityQueue<>((a, b) -> b - a);
77+
double ans = 1e9;
78+
int tot = 0;
79+
for (var e : t) {
80+
tot += e.q;
81+
pq.offer(e.q);
82+
if (pq.size() == k) {
83+
ans = Math.min(ans, tot * e.x);
84+
tot -= pq.poll();
85+
}
86+
}
87+
return ans;
88+
}
89+
}
90+
91+
class Pair {
92+
double x;
93+
int q;
94+
95+
Pair(int q, int w) {
96+
this.q = q;
97+
this.x = (double) w / q;
98+
}
99+
}
100+
```
101+
102+
### **C++**
103+
104+
```cpp
105+
class Solution {
106+
public:
107+
double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int k) {
108+
int n = quality.size();
109+
vector<pair<double, int>> t(n);
110+
for (int i = 0; i < n; ++i) {
111+
t[i] = {(double) wage[i] / quality[i], quality[i]};
112+
}
113+
sort(t.begin(), t.end());
114+
priority_queue<int> pq;
115+
double ans = 1e9;
116+
int tot = 0;
117+
for (auto& [x, q] : t) {
118+
tot += q;
119+
pq.push(q);
120+
if (pq.size() == k) {
121+
ans = min(ans, tot * x);
122+
tot -= pq.top();
123+
pq.pop();
124+
}
125+
}
126+
return ans;
127+
}
128+
};
129+
```
57130
131+
### **Go**
132+
133+
```go
134+
func mincostToHireWorkers(quality []int, wage []int, k int) float64 {
135+
t := []pair{}
136+
for i, q := range quality {
137+
t = append(t, pair{float64(wage[i]) / float64(q), q})
138+
}
139+
sort.Slice(t, func(i, j int) bool { return t[i].x < t[j].x })
140+
tot := 0
141+
var ans float64 = 1e9
142+
pq := hp{}
143+
for _, e := range t {
144+
tot += e.q
145+
heap.Push(&pq, e.q)
146+
if pq.Len() == k {
147+
ans = min(ans, float64(tot)*e.x)
148+
tot -= heap.Pop(&pq).(int)
149+
}
150+
}
151+
return ans
152+
}
153+
154+
func min(a, b float64) float64 {
155+
if a < b {
156+
return a
157+
}
158+
return b
159+
}
160+
161+
type pair struct {
162+
x float64
163+
q int
164+
}
165+
166+
type hp struct{ sort.IntSlice }
167+
168+
func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
169+
func (h *hp) Pop() interface{} {
170+
a := h.IntSlice
171+
v := a[len(a)-1]
172+
h.IntSlice = a[:len(a)-1]
173+
return v
174+
}
175+
func (h *hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] }
58176
```
59177

60178
### **...**
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
class Solution {
2+
public:
3+
double mincostToHireWorkers(vector<int>& quality, vector<int>& wage, int k) {
4+
int n = quality.size();
5+
vector<pair<double, int>> t(n);
6+
for (int i = 0; i < n; ++i) {
7+
t[i] = {(double) wage[i] / quality[i], quality[i]};
8+
}
9+
sort(t.begin(), t.end());
10+
priority_queue<int> pq;
11+
double ans = 1e9;
12+
int tot = 0;
13+
for (auto& [x, q] : t) {
14+
tot += q;
15+
pq.push(q);
16+
if (pq.size() == k) {
17+
ans = min(ans, tot * x);
18+
tot -= pq.top();
19+
pq.pop();
20+
}
21+
}
22+
return ans;
23+
}
24+
};
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
func mincostToHireWorkers(quality []int, wage []int, k int) float64 {
2+
t := []pair{}
3+
for i, q := range quality {
4+
t = append(t, pair{float64(wage[i]) / float64(q), q})
5+
}
6+
sort.Slice(t, func(i, j int) bool { return t[i].x < t[j].x })
7+
tot := 0
8+
var ans float64 = 1e9
9+
pq := hp{}
10+
for _, e := range t {
11+
tot += e.q
12+
heap.Push(&pq, e.q)
13+
if pq.Len() == k {
14+
ans = min(ans, float64(tot)*e.x)
15+
tot -= heap.Pop(&pq).(int)
16+
}
17+
}
18+
return ans
19+
}
20+
21+
func min(a, b float64) float64 {
22+
if a < b {
23+
return a
24+
}
25+
return b
26+
}
27+
28+
type pair struct {
29+
x float64
30+
q int
31+
}
32+
33+
type hp struct{ sort.IntSlice }
34+
35+
func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
36+
func (h *hp) Pop() interface{} {
37+
a := h.IntSlice
38+
v := a[len(a)-1]
39+
h.IntSlice = a[:len(a)-1]
40+
return v
41+
}
42+
func (h *hp) Less(i, j int) bool { return h.IntSlice[i] > h.IntSlice[j] }

0 commit comments

Comments
 (0)