leetcode 贪心_Leetcode 1383 最大的团队表现值(贪心)

Description

公司有编号为 1 到 n 的 n 个工程师,给你两个数组 speed 和 efficiency ,其中 speed[i] 和 efficiency[i] 分别代表第 i 位工程师的速度和效率。请你返回由最多 k 个工程师组成的 最大团队表现值 ,由于答案可能很大,请你返回结果对 10^9 + 7 取余后的结果。

团队表现值 的定义为:一个团队中「所有工程师速度的和」乘以他们「效率值中的最小值」。

Examples Input

n = 6

speed = [2,10,3,1,5,8]

efficiency = [5,4,3,9,7,2]

k = 2

Examples Output

60

思路

记得 leetcode 每场周赛至少有一个 dp 题,可能太久没打了,形势变了 QAQ

这道题乍一看「团队表现值」的计算中有着「效率值中的最小值」这一因素,那我们从这一点入手。

思考假设当前已经确定了效率的最小值 $x$,那么员工便可以从效率大于等于 $x$ 的人中最多找 speed 前 $k$ 个即可。

而直接循环处理这一个过程显然时间复杂度是 $O(n^2)$ 的不可取,这里还有一个递推的因素在里面,即工作效率大于 $x$ 的人必定工作效率大于 $x-1$。

于是我们按照工作效率从大到小给所有人排序,然后开始遍历。

使用 multiset 维护当前所有工作效率大于等于 $x$ 的人的 speed,当然用优先队列维护也可以。

在每一次处理工作效率为 $x$ 的循环中,首先将工作效率为 $x$ 的人的 speed 加入到 multiset 里(efficiency 大于 $x$ 之前的循环已经加过了),然后调整 multiset 的内容,删除 speed 最小的元素直到其容量小于等于 $k$,这里我用了 tmpadd 维护了 multiset 中所有元素的和。

再就找每个循环处理结果的最大值便好了,记得取模,当前「团队表现值」等于 $x \times tmpadd$。

需要注意的一点:题中的最大值指 $x \times tmpadd$ 的最大值再取模,而不是 $x \times tmpadd$ 取模的最大值。

AC 代码

const int maxn = 1e5 + 10;

const int mod = 1e9 + 7;

const double eps = 1e-8;

class Solution {

public:

int maxPerformance(int n, vector &speed, vector &efficiency,

int k) {

multiset st;

map> mp;

for (int i = 0; i < n; i++) {

mp[efficiency[i]].push_back(speed[i]);

}

long long ans = 0, tmpadd = 0; // tmpadd 为 st 中元素之和(员工速度和)

for (auto i = mp.rbegin(); i != mp.rend(); i++) {

for (auto s : i->second) {

st.insert(s);

tmpadd += s;

}

int stsize = max(0, (int)st.size() - k);

for (int j = 0; j < stsize; j++) {

tmpadd -= *st.begin();

st.erase(st.begin());

}

long long tmp = i->first * tmpadd;

ans = max(ans, tmp);

}

return ans % mod;

}

};

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值