目录
一、题目
1、题目描述
你有
n
个工作和m
个工人。给定三个数组:difficulty
,profit
和worker
,其中:
difficulty[i]
表示第i
个工作的难度,profit[i]
表示第i
个工作的收益。worker[i]
是第i
个工人的能力,即该工人只能完成难度小于等于worker[i]
的工作。每个工人 最多 只能安排 一个 工作,但是一个工作可以 完成多次 。
- 举个例子,如果 3 个工人都尝试完成一份报酬为
$1
的同样工作,那么总收益为$3
。如果一个工人不能完成任何工作,他的收益为$0
。返回 在把工人分配到工作岗位后,我们所能获得的最大利润 。
2、接口描述
python3
class Solution:
def maxProfitAssignment(self, difficulty: List[int], profit: List[int], worker: List[int]) -> int:
cpp
class Solution {
public:
int maxProfitAssignment(vector<int>& difficulty, vector<int>& profit, vector<int>& worker) {
}
};
3、原题链接
二、解题报告
1、思路分析
很经典的贪心问题
我们将任务按照双关键字升序排序,第一关键字:难度,第二关键字:利润
将员工也升序排序
然后顺序遍历员工,用一个指针维护当前能够干的任务
排序后有个好处,前面员工能干的,后面的员工也能干
我们遍历员工的时候不断地把能干的任务拿进来,然后这个员工应该干当前能干的任务当中利润最大那个
2、复杂度
时间复杂度: O(nlogn + mlogm)空间复杂度:O(n)
3、代码详解
python3
from sortedcontainers import SortedList
class Solution:
def maxProfitAssignment(self, difficulty: List[int], profit: List[int], worker: List[int]) -> int:
n = len(difficulty)
ma = i = ret = 0
dp = sorted(list(zip(difficulty, profit)))
for w in sorted(worker):
while i < n and dp[i][0] <= w:
ma = max(dp[i][1], ma)
i += 1
ret += ma
return ret
cpp
class Solution {
public:
int maxProfitAssignment(vector<int>& difficulty, vector<int>& profit, vector<int>& worker) {
vector<pair<int, int>> dp;
int n = difficulty.size();
int i = 0, ma = 0, ret = 0;
for (i = 0; i < n; i ++) dp.emplace_back(difficulty[i], profit[i]);
sort(dp.begin(), dp.end());
sort(worker.begin(), worker.end());
i = 0;
for (int w : worker) {
while (i < n && dp[i].first <= w) ma = max(ma, dp[i ++].second);
ret += ma;
}
return ret;
}
};