LeetCode·每日一题·857.雇佣K名工人的最低成本·贪心

链接:https://leetcode.cn/problems/minimum-cost-to-hire-k-workers/solution/-by-xun-ge-v-53vl/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 

题目

 

示例

 

思路

解题思路
1、最小总工资=选中的K个工人中最高的工人成本*总的工作质量
2、计算每个工人成本=工资/工作质量,按照工作成本升序排列
3、按照工作质量维护大顶堆,先加入成本最低的K个工人对应的工作量到大顶堆中,此时,第k个工人(从1开始的第K个,也就是排序的数组的k-1)的成本是所有人的成本。此时计算一个总工资。
4、后续遍每一个工作,某个工人的成本很高,但是,可能该工人的工作量可能较低,因此,虽然总成本升高,但是,如果总的工作质量下降,那么,乘积也就是总工资可能下降,也就是堆顶的最大值出堆,后续工作的工作量入堆,计算最新的总工资,并更最小值比较,遍历完成就得到最低的总工资。

代码

typedef struct node
{
    int q;//工作量
    double unit_price;//工作单价
}node;

int heap[10005];//固定长度的大顶堆数组
int idx;//当前堆中的元素个数
int tk;//堆长度
int q;//当前堆中所有工人的工作量之和

void up(int cur)//堆的上移操作
{
    if(cur==1)
    {
        return;
    }
    if(heap[cur]>heap[cur>>1])
    {
        int t=heap[cur];
        heap[cur]=heap[cur>>1];
        heap[cur>>1]=t;
        up(cur>>1);
    }
}

void down(int cur)//堆的下移操作
{
    int t=cur;
    if(cur<<1<=idx&&heap[t]<heap[cur<<1])
    {
        t=cur<<1;
    }
    if((cur<<1|1)<=idx&&heap[t]<heap[(cur<<1)|1])
    {
        t=cur<<1|1;
    }
    if(t!=cur)
    {
        int temp=heap[t];
        heap[t]=heap[cur];
        heap[cur]=temp;
        down(t);
    }
}

void push(int val)//加入新节点
{
    if(idx<tk)//堆未满,加入堆末尾再上移
    {
        q+=val;//更新总工作量
        heap[++idx]=val;
        up(idx);
    }
    else//堆已满,替换堆顶再下移
    {
        q+=val-heap[1];//更新总工作量
        heap[1]=val;
        down(1);
    }
}

int cmp(const void *a,const void *b)//依工作单价升序排序
{
    if(((node *)a)->unit_price<((node *)b)->unit_price)
    {
        return -1;
    }
    return 1;
}

double mincostToHireWorkers(int* quality, int qualitySize, int* wage, int wageSize, int k){
    int i;
    double re=99999999999,t;
    idx=q=0;
    tk=k;
    node arr[qualitySize];
    for(i=0;i<qualitySize;i++)//填充arr数组
    {
        arr[i].q=quality[i];
        arr[i].unit_price=(double)wage[i]/quality[i];
    }

    qsort(arr,qualitySize,sizeof(node),cmp);//快排
    for(i=0;i<k-1;i++)//加入工人未满
    {
        push(arr[i].q);
    }
    for(;i<qualitySize;i++)//加入工人已满
    {
        push(arr[i].q);
        if((t=(double)q*arr[i].unit_price)<re)//更新re值
        {
            
            re=t;
        }
    }
    return re;
}


作者:xun-ge-v
链接:https://leetcode.cn/problems/minimum-cost-to-hire-k-workers/solution/-by-xun-ge-v-53vl/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值