2023-05-18:有 n 名工人。 给定两个数组 quality 和 wage , 其中,quality[i] 表示第 i 名工人的工作质量,其最低期望工资为 wage[i] 。 现在我们想雇佣 环球最资讯

2023-05-18:有 n 名工人。 给定两个数组 quality 和 wage ,

其中,quality[i] 表示第 i 名工人的工作质量,其最低期望工资为 wage[i] 。


(资料图)

现在我们想雇佣 k 名工人组成一个工资组。在雇佣 一组 k 名工人时,

我们必须按照下述规则向他们支付工资:

对工资组中的每名工人,应当按其工作质量与同组其他工人的工作质量的比例来支付工资。

工资组中的每名工人至少应当得到他们的最低期望工资。

给定整数 k ,返回 组成满足上述条件的付费群体所需的最小金额。

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

输出: 105.00000。

答案2023-05-18:

解题步骤:

1.构造 Employee 结构体,存储每个员工的工作质量和垃圾系数(wage / quality)。

2.按照垃圾系数从小到大对所有员工进行排序。

3.维护一个大小为 k 的小根堆,表示当前最低期望工资组中的 k 名工人的工作质量。

4.遍历所有员工,如果堆未满,则将该员工加入堆中并更新最低期望工资。如果堆已满,则检查当前员工能否替换堆顶元素,如果可以,则弹出堆顶元素并将当前员工入堆,更新最低期望工资。

5.最终返回最低期望工资即可。

注意事项:

使用 golang 内置的 container/heap 库来实现小根堆。

在比较垃圾系数大小时,需要使用小于等于号,因为可能存在两个员工的垃圾系数完全相等的情况。

时间复杂度:排序所需的时间为 O(nlogn),遍历员工数组时每个员工会入堆一次,出堆一次,即共进行了 2n 次操作,而小根堆的插入和弹出操作时间复杂度均为 O(logk),因此总时间复杂度为 O(nlogn + nlogk)。

空间复杂度:除给定数组外,我们还需要构造 Employee 结构体,以及维护大小为 k 的小根堆,因此需要额外使用 O(n) 空间来存储结构体数组,并且在堆满时可能需要对堆进行调整,最多需要 O(k) 的额外空间。因此总空间复杂度为 O(n + k)。

go完整代码如下:
package mainimport ("container/heap""fmt""sort")type Employee struct {RubbishDegree float64Quality       int}func NewEmployee(w, q int) Employee {return Employee{RubbishDegree: float64(w) / float64(q), Quality: q}}type EmployeeHeap []intfunc (h EmployeeHeap) Len() int            { return len(h) }func (h EmployeeHeap) Less(i, j int) bool  { return h[i] > h[j] }func (h EmployeeHeap) Swap(i, j int)       { h[i], h[j] = h[j], h[i] }func (h *EmployeeHeap) Push(x interface{}) { *h = append(*h, x.(int)) }func (h *EmployeeHeap) Pop() interface{} {n := len(*h)x := (*h)[n-1]*h = (*h)[:n-1]return x}func min(a, b float64) float64 {if a < b {return a}return b}func mincostToHireWorkers(quality []int, wage []int, k int) float64 {n := len(quality)employees := make([]Employee, n)for i := range quality {employees[i] = NewEmployee(wage[i], quality[i])}sort.Slice(employees, func(i, j int) bool {return employees[i].RubbishDegree <= employees[j].RubbishDegree})minTops := &EmployeeHeap{}heap.Init(minTops)ans, qualitySum := 1e9, 0for i := 0; i < n; i++ {curQuality := employees[i].Qualityif minTops.Len() < k { // 堆没满qualitySum += curQualityheap.Push(minTops, curQuality)if minTops.Len() == k {ans = min(ans, float64(qualitySum)*employees[i].RubbishDegree)}} else { // 来到当前员工的时候,堆是满的!// 当前员工的能力,可以把堆顶干掉,自己进来!if top := (*minTops)[0]; top > curQuality {heap.Pop(minTops)qualitySum += curQuality - topheap.Push(minTops, curQuality)ans = min(ans, float64(qualitySum)*employees[i].RubbishDegree)}}}return ans}func main() {quality := []int{10, 20, 5}wage := []int{70, 50, 30}k := 2result := mincostToHireWorkers(quality, wage, k)fmt.Println(result)}
rust完整代码如下:
struct Employee {    rubbish_degree: f64,    quality: i32,}impl Employee {    fn new(w: i32, q: i32) -> Self {        let rubbish_degree = w as f64 / q as f64;        Self {            rubbish_degree,            quality: q,        }    }}fn mincost_to_hire_workers(quality: Vec, wage: Vec, k: i32) -> f64 {    let n = quality.len();    let mut employees = Vec::with_capacity(n);    for i in 0..n {        employees.push(Employee::new(wage[i], quality[i]));    }    // 只根据垃圾指数排序    // 要价 / 能力    employees.sort_by(|a, b| a.rubbish_degree.partial_cmp(&b.rubbish_degree).unwrap());    // 请维持力量最小的前K个力量    // 大根堆!门槛堆!    let mut min_tops = std::collections::BinaryHeap::new();    let mut ans = std::f64::MAX;    let mut quality_sum = 0;    for i in 0..n {        // i : 依次所有员工的下标        // quality_sum : 进入堆的力量总和!        // cur_quality当前能力        let cur_quality = employees[i].quality;        if min_tops.len() < k as usize {            // 堆没满            quality_sum += cur_quality;            min_tops.push(cur_quality);            if min_tops.len() == k as usize {                ans = ans.min(quality_sum as f64 * employees[i].rubbish_degree);            }        } else {            // 来到当前员工的时候,堆是满的!            // 当前员工的能力,可以把堆顶干掉,自己进来!            if let Some(top) = min_tops.peek() {                if *top > cur_quality {                    quality_sum += cur_quality - min_tops.pop().unwrap();                    min_tops.push(cur_quality);                    ans = ans.min(quality_sum as f64 * employees[i].rubbish_degree);                }            }        }    }    ans}fn main() {    let quality = vec![10, 20, 5];    let wage = vec![70, 50, 30];    let k = 2;    let result = mincost_to_hire_workers(quality, wage, k);    println!("{}", result);}
c完整代码如下:
#include #include #include typedef struct Employee {    double rubbishDegree;    int quality;} Employee;int cmp(const void* a, const void* b) {    Employee* pa = (Employee*)a;    Employee* pb = (Employee*)b;    if (pa->rubbishDegree < pb->rubbishDegree) {        return -1;    }    else if (pa->rubbishDegree > pb->rubbishDegree) {        return 1;    }    else {        return 0;    }}double mincostToHireWorkers(int* quality, int qualitySize, int* wage, int wageSize, int k) {    int n = qualitySize;    Employee* employees = (Employee*)malloc(n * sizeof(Employee));    for (int i = 0; i < n; i++) {        employees[i].quality = quality[i];        employees[i].rubbishDegree = (double)wage[i] / (double)quality[i];    }    qsort(employees, n, sizeof(Employee), cmp);    int* minTops = (int*)malloc(k * sizeof(int));    int topIndex = -1;    double ans = INT_MAX;    int qualitySum = 0;    for (int i = 0; i < n; i++) {        int curQuality = employees[i].quality;        if (topIndex < k - 1) {            qualitySum += curQuality;            minTops[++topIndex] = curQuality;            if (topIndex == k - 1) {                ans = qualitySum * employees[i].rubbishDegree;            }        }        else {            if (minTops[0] > curQuality) {                qualitySum += curQuality - minTops[0];                minTops[0] = curQuality;                ans = qualitySum * employees[i].rubbishDegree;                // 调整,使堆继续保持最小堆的性质                for (int j = 0; j < k - 1; j++) {                    if (minTops[j] > minTops[j + 1]) {                        int tmp = minTops[j];                        minTops[j] = minTops[j + 1];                        minTops[j + 1] = tmp;                    }                    else {                        break;                    }                }            }        }    }    free(employees);    free(minTops);    return ans;}int main() {    int quality[] = { 10,20,5 };    int wage[] = { 70,50,30 };    int k = 2;    double result = mincostToHireWorkers(quality, sizeof(quality) / sizeof(int), wage, sizeof(wage) / sizeof(int), k);    printf("%lf\n", result);     return 0;}
c++完整代码如下:
#include #include #include #include #include using namespace std;struct Employee {    double rubbishDegree;    int quality;    Employee() = default;    Employee(int w, int q) : rubbishDegree(static_cast(w) / static_cast(q)), quality(q) {}    bool operator<(const Employee& other) const {        return rubbishDegree < other.rubbishDegree;    }};double mincostToHireWorkers(vector& quality, vector& wage, int k) {    int n = quality.size();    vector employees(n);    for (int i = 0; i < n; i++) {        employees[i] = Employee(wage[i], quality[i]);    }    // 只根据垃圾指数排序    sort(employees.begin(), employees.end());    // 请维持力量最小的前K个力量    // 大根堆!门槛堆!    priority_queue minTops;    double ans = numeric_limits::max();    for (int i = 0, qualitySum = 0; i < n; i++) {        // i : 依次所有员工的下标        // qualitySum : 进入堆的力量总和!        // curQuality当前能力        int curQuality = employees[i].quality;        if (minTops.size() < k) { // 堆没满            qualitySum += curQuality;            minTops.push(curQuality);            if (minTops.size() == k) {                ans = min(ans, qualitySum * employees[i].rubbishDegree);            }        }        else { // 来到当前员工的时候,堆是满的!            // 当前员工的能力,可以把堆顶干掉,自己进来!            if (minTops.top() > curQuality) {                //              qualitySum -= minTops.top();                //              qualitySum += curQuality;                //              minTops.pop();                //              minTops.push(curQuality);                qualitySum += curQuality - minTops.top();                minTops.pop();                minTops.push(curQuality);                ans = min(ans, qualitySum * employees[i].rubbishDegree);            }        }    }    return ans;}int main() {    vector quality = { 10, 20, 5 };    vector wage = { 70, 50, 30 };    int k = 2;    double result = mincostToHireWorkers(quality, wage, k);    cout << result << endl; // 105    return 0;}

标签:

最近更新

2023-05-18:有 n 名工人。 给定两个数组 quality 和 wage , 其中,quality[i] 表示第 i 名工人的工作质量,其最低期望工资为 wage[i] 。 现在我们想雇佣 环球最资讯
2023-05-18 22:40:45
全球今热点:内蒙古自治区呼和浩特市2023-05-18 17:41发布大风蓝色预警
2023-05-18 21:57:13
宁波中小企业走进国际消费品博览会:让更多消费好物走出国门 世界热文
2023-05-18 21:08:40
环球热讯:首届“筑宁杯”运动会顺利举办
2023-05-18 20:22:59
极米科技: 中国国际金融股份有限公司关于极米科技2022年度持续督导跟踪报告
2023-05-18 19:19:56
苹果手机丢了已关机_苹果手机丢了找客服|世界播资讯
2023-05-18 18:47:05
IPO估值 | 埃科光电:工业相机国产替代基本实现 未来想象空间或有限|每日观察
2023-05-18 18:07:59
数毛社Steam Deck测评:新三A大作性能表现开始吃紧 天天新动态
2023-05-18 17:04:59
世界热点评!中国一重涨停
2023-05-18 16:50:37
环球观热点:全国31地同步行动,严厉打击为电信网络诈骗提供“简易组网GOIP”通话服务的犯罪团伙
2023-05-18 16:02:18
天天视讯!安徽马鞍山:把修复长江生态环境摆在压倒性位置
2023-05-18 15:49:32
主力资金监控:拓尔思净买入超11亿|环球实时
2023-05-18 15:09:30
天天热消息:最新!萨尔图区干部任免名单
2023-05-18 13:46:53
环球观热点:购买基金的平台有哪些 新手如何购买基金
2023-05-18 12:57:54
输入密码的前一秒,民警敲响房门…成功止损150万!_全球今日讯
2023-05-18 11:59:28
全球关注:关于张柏芝大方晒出三胎儿子正脸照及张柏芝大方晒出三胎儿子正脸照详情
2023-05-18 10:55:31
热推荐:香港大学更改配房安排:首年入住本地生须与非本地生同房
2023-05-18 10:30:18
贵州省安顺市2023-05-18 07:46发布暴雨黄色预警 环球看热讯
2023-05-18 10:01:01
福建省东山县发布大雾黄色预警
2023-05-18 09:37:46
虫字旁的字表示都和什么有关_虫字旁表示与什么有关
2023-05-18 09:14:14
世界快报:欧陆通05月17日获深股通增持7.22万股
2023-05-18 08:28:25
2023下半年宏观经济与资产展望:向稳态增速回归
2023-05-18 07:27:31
微动态丨皇马0-4惨案1人是罪人!防守3次漏人+只盯哈兰德,国米要吸取教训
2023-05-18 06:27:12
《区块链+无废城市建设白皮书》2023年底发布 深度探讨固废管理创新和可持续发展-全球快看点
2023-05-18 05:35:20
硫酸肼 环球观天下
2023-05-18 03:53:05
my happy holiday手抄报_my happy day手抄报-消息
2023-05-18 00:53:31
高温下热浪中,济南部分工地错时施工“避暑”
2023-05-17 22:32:07
全球速看:自设市以来,深圳首次出现人口负增长,长沙的机会来了
2023-05-17 21:28:20
二本高考扩招院校排名 2022年高考容易捡漏的二本大学有哪些
2023-05-17 20:28:40
泽熙投反对票 华丽家族年度股东大会18项议案全部遭否决
2023-05-17 19:30:45