C++ 4 lines, sort, bucket sort, and bucked sort with two pointers
This solution sorts levels and assigns the maximum profit among all jobs with equal or lower level:\n\n1. Load levels and profits into a sorted map.\n2. Update 
This solution sorts levels and assigns the maximum profit among all jobs with equal or lower level:\n\n1. Load levels and profits into a sorted map.\n2. Update the map so that each level has the maximum possible profit. Practically, if the previous level has higher profit, we assign that profit to the current level.\n3. For each worker, search the map to get the maximum profit for the worker\'s level.\n\nThe complexity is O((n + m) log n), where n and m is the number of jobs and workers respectfully.\n```\nint maxProfitAssignment(vector<int>& lv, vector<int>& profit, vector<int>& worker) {\n  map<int, int> m = { { 0, 0 } };\n  for (auto i = 0; i < lv.size(); ++i) m[lv[i]] = max(m[lv[i]], profit[i]);\n  for (auto it = next(m.begin()); it != m.end(); ++it) it->second = max(it->second, prev(it)->second);\n  return accumulate(begin(worker), end(worker), 0, [&](int s, int w) {return s + prev(m.upper_bound(w))->second;});\n}\n```\nAs a bonus, below is the solution that uses bucket sort. It requires, however, additional memory but the runtime complexity is O(N + m), where N is the number of levels (100,000 in our case). The second solution is only slightly faster in OJ (100 vs. 110 ms), probably because n is signifficantly smaller than N in the test cases.\n```\nint maxProfitAssignment(vector<int>& lv, vector<int>& profit, vector<int>& worker) {\n  int m[100001] = {};\n  for (auto i = 0; i < lv.size(); ++i) m[lv[i]] = max(m[lv[i]], profit[i]);\n  for (auto i = 1; i < 100001; ++i) m[i] = max(m[i], m[i - 1]);\n  return accumulate(begin(worker), end(worker), 0, [&](int s, int w) { return s + m[w]; });\n}\n```\nI also checked the sort and two-pointer solution by @lee215. That solution requires two sorts, that\'s why my preference was to sort once and fix profits in the linear time. Anyway, I adopted the two-pointer solution to use the bucket sort. Note that I store the number of workers with a given level in the second array.\n```\nint maxProfitAssignment(vector<int>& lv, vector<int>& profit, vector<int>& worker) {\n  int m[100001] = {}, w[100001] = {}, p = 0, max_p = 0;\n  for (auto i = 0; i < lv.size(); ++w[worker[i++]]) m[lv[i]] = max(m[lv[i]], profit[i]);\n  return accumulate(begin(w), end(w), 0, [&](int s, int w) { max_p = max(max_p, m[p++]); return s + max_p * w; });\n}\n```
[]