Trace
你可以安排的最多任务数目
传送门:https://leetcode-cn.com/problems/maximum-number-of-tasks-you-can-assign/
给你 n
个任务和 m
个工人。每个任务需要一定的力量值才能完成,需要的力量值保存在下标从 0 开始的整数数组 tasks
中,第 i
个任务需要 tasks[i]
的力量才能完成。每个工人的力量值保存在下标从 0 开始的整数数组 workers
中,第 j
个工人的力量值为 workers[j]
。每个工人只能完成 一个 任务,且力量值需要 大于等于 该任务的力量要求值(即 workers[j] >= tasks[i]
)。
除此以外,你还有 pills
个神奇药丸,可以给 一个工人的力量值 增加 strength
。你可以决定给哪些工人使用药丸,但每个工人 最多 只能使用 一片 药丸。
给你下标从 0 开始的整数数组tasks
和 workers
以及两个整数 pills
和 strength
,请你返回 最多 有多少个任务可以被完成。
示例 1:
1 | 输入:tasks = [3,2,1], workers = [0,3,3], pills = 1, strength = 1 |
示例 2:
1 | 输入:tasks = [5,4], workers = [0,0,0], pills = 1, strength = 5 |
示例 3:
1 | 输入:tasks = [10,15,30], workers = [0,10,10,10,10], pills = 3, strength = 10 |
示例 4:
1 | 输入:tasks = [5,9,8,5,9], workers = [1,6,4,2,6], pills = 1, strength = 5 |
提示:
n == tasks.length
m == workers.length
1 <= n, m <= 5 * 1e4
0 <= pills <= m
0 <= tasks[i], workers[j], strength <= 1e9
思路
二分+贪心
假如使用药丸以后,$k$个任务可以被完成,那么小于$k$个任务也一定能完成,求满足条件的最大的$k$,考虑二分。
需要检查$mid$个任务是否可以被完成,如何检查?
假设可以完成$k$个任务,那么给$workers$中力量最大的k个人使用药丸以后,去完成$tasks$中需要力量最小的$k$个任务,一定可以完成。
从易到难遍历最简单的$k$个任务,然后从最强的$k$个$workers$中由弱到强匹配,看能否完成(由弱到强匹配为什么最优?因为假如当前最弱$worker$可以满足,那么任意其它$worker$也可以满足,交换后仍然可行);如果不能完成,则给当前工人使用药丸,然后匹配能满足的最难的任务A(为什么最优,因为如果匹配最简单的任务B,另一个$worker$也可以满足A,交换后仍然可行)如果存在不能匹配则失败。
程序
1 | class Solution { |
auto it=upper_bound(t.begin(),t.end(),now_strength);
auto it=t.upper_bound(now_strength);
使用上面语句会$TLE$,下面$AC$,其中$t$的数据类型为$multiset$。
调用$multiset$自身的$upper_bound$是在树上查找,时间复杂度$O(logn)$;
用$function$调用$upper_bound$时间复杂度为$O(n)$。
时间复杂度:$O(nlogn+mlogm+min(m,n)log^2(min(m,n)))$