LeetCode每日一题(857. Minimum Cost to Hire K Workers)

给定n个工人及其质量和期望薪资,找出雇佣k名工人并满足薪资比例和最低期望薪资条件的最低总成本。通过计算wage/quality得到工人能接受的单位质量薪资下限,按此排序,选择最小成本组合。处理浮点数计算的精度问题增加了实现难度。
摘要由CSDN通过智能技术生成

There are n workers. You are given two integer arrays quality and wage where quality[i] is the quality of the ith worker and wage[i] is the minimum wage expectation for the ith worker.

We want to hire exactly k workers to form a paid group. To hire a group of k workers, we must pay them according to the following rules:

Every worker in the paid group should be paid in the ratio of their quality compared to other workers in the paid group.
Every worker in the paid group must be paid at least their minimum wage expectation.
Given the integer k, return the least amount of money needed to form a paid group satisfying the above conditions. Answers within 10-5 of the actual answer will be accepted.

Example 1:

Input: quality = [10,20,5], wage = [70,50,30], k = 2
Output: 105.00000

Explanation: We pay 70 to 0th worker and 35 to 2nd worker.

Example 2:

Input: quality = [3,1,10,10,1], wage = [4,8,2,2,7], k = 3
Output: 30.66667

Explanation: We pay 4 to 0th worker, 13.33333 to 2nd and 3rd workers separately.

Constraints:

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

当 rust 遇到浮点数, 就是一切噩梦的开始

题目其实不难, 被周边问题搞了个半死。

我们定义 ratio = wage / quality, 它代表工所能接受的单位 quality 所付 wage 的下限, 我们将工人按 ratio 排序, 这样我们遍历工人的时候 ratio 是非严格递增的(可能存在 ratio 相等的情况), 因为 ratio 是个下限, 所以我们选中的工人一定是按照最后一个进来的工人的 ratio 来计算工资, 高于这个 ratio 我们赔钱, 低于这个 ratio 至少最后进来的那个工人不干。我们将选中的工人的 quality 相加然后乘以 ratio 就是我们实际要支付的 wage。到这里我们就可以把问题转化的更简单一点, 对于任何一个工人, 我们要找到在他之前遍历的 k-1 个 quality 最小的工人, 然后加上当前工人的 quality, 用这个加和乘以当前工人的 ratio 就是如果选中当前工人所要支付的最低 wage。从这些值中挑出最小的就是我们要的答案。

问题搞清楚了,但是其实这才完成了一半,因为我们最终要的答案是浮点数,浮点数不准这点大家都知道,但题目还偏偏要求我们对比浮点数。像 python 这种对数字运算天然友好的语言可能还好点, 但像 rust 这种我只能定义一个类型来表达分数,并定义其相关运算,整个过程中我们用该类型进行计算和对比,最后将其转化为浮点数输出答案。所以代码看着会比较冗长, 大家见谅


use std::{
   collections::BinaryHeap, ops::Mul};

#[derive(Debug, Eq)]
struct Fraction(i64, i64);

impl Fraction {
   
    fn new(numerator: i32, denominator: i32) -> Self {
   
        let gcd = Solution::gcd(numerator as i64, denominator as i64);
        Self(numerator as i64 / gcd, denominator as 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值