You have n jobs and m workers. You are given three arrays: difficulty, profit, and worker where:


	difficulty[i] and profit[i] are the difficulty and the profit of the ith job, and
	worker[j] is the ability of jth worker (i.e., the jth worker can only complete a job with difficulty at most worker[j]).


Every worker can be assigned at most one job, but one job can be completed multiple times.


	For example, if three workers attempt the same job that pays $1, then the total profit will be $3. If a worker cannot complete any job, their profit is $0.


Return the maximum profit we can achieve after assigning the workers to the jobs.

&nbsp;
Example 1:

Input: difficulty = [2,4,6,8,10], profit = [10,20,30,40,50], worker = [4,5,6,7]
Output: 100
Explanation: Workers are assigned jobs of difficulty [4,4,6,6] and they get a profit of [20,20,30,30] separately.


Example 2:

Input: difficulty = [85,47,57], profit = [24,66,99], worker = [40,25,25]
Output: 0


&nbsp;
Constraints:


	n == difficulty.length
	n == profit.length
	m == worker.length
	1 &lt;= n, m &lt;= 104
	1 &lt;= difficulty[i], profit[i], worker[i] &lt;= 105


class Solution:
    #Time-Complexity: O(n + nlogn + n + mlog(n)) -> O((n+m) *logn)
    #Space-Complexity: O(n)
    def maxProfitAssignment(self, difficulty: List[int], profit: List[int], worker: List[int]) -> int:
        #Approach: First of all, linearly traverse each and every corresponding index
        #position of first two input arrays: difficulty and profit to group each
        #item by 1-d array and put it in separate 2-d array. Then, sort the 2-d array
        #by increasing difficulty of the job! Then, for each worker, perform binary
        #search and consistently update the max profit the current worker can work and
        #earn! Add this value to answer variable, which is cumulative for all workers!
        #this will be the result returned at the end!
        arr = []
        for i in range(len(difficulty)):
            arr.append([difficulty[i], profit[i]])
        #sort by difficulty!
        arr.sort(key = lambda x: x[0])
        #then, I need to update the maximum profit up to each and every item!
        maximum = float(-inf)
        for j in range(len(arr)):
            maximum = max(maximum, arr[j][1])
            arr[j][1] = maximum
        ans = 0
        #iterate through each and every worker!
        for w in worker:
            bestProfit = 0
            #define search space to perform binary search!
            L, R = 0, len(arr) - 1
            #as long as search space has at least one element to consider or one job,
            #continue iterations of binary search!
            while L <= R:
                mid = (L + R) // 2
                mid_e = arr[mid]
                #check if current job has difficulty that is manageable!
                if(mid_e[0] <= w):
                    bestProfit = max(bestProfit, mid_e[1])
                    #we still need to search right and try higher difficulty
                    #jobs that might yield higher profit!
                    L = mid + 1
                    continue
                else:
                    R = mid - 1
                    continue
            #once we break from while loop and end binary search, we should have
            #found bestProfit for current worker performing task that is manageable!
            ans += bestProfit
        return ans
class Solution {
    public int maxProfitAssignment(int[] difficulty, int[] profit, int[] worker) {
        PriorityQueue<int[]> pq=new PriorityQueue<>((a,b)->(b[1]-a[1]));
        for(int i=0;i<profit.length;i++)
        {
            pq.add(new int[]{difficulty[i],profit[i]});
        }
        Arrays.sort(worker);
        int p=0;
        for(int i=worker.length-1;i>=0 && !pq.isEmpty();i--)
        {
            if(worker[i]>=pq.peek()[0])
                p=p+pq.peek()[1];
            else
            {
                while(!pq.isEmpty() && worker[i]<pq.peek()[0])
                    pq.poll();
                if(!pq.isEmpty())
                  p=p+pq.peek()[1];
            }
        }
        return p;
    }
}
class Solution {
public:
    static bool cmp(pair<int,int>a, pair<int,int>b){
        if(a.first == b.first){
            return a.second<b.second;
        }

        return a.first>b.first;
    }
    int maxProfitAssignment(vector<int>& difficulty, vector<int>& profit, vector<int>& worker) {
        int ans = 0;
        vector<pair<int,int>>vp;
        for(int i = 0; i<profit.size(); i++){
            vp.push_back({profit[i], difficulty[i]});
        }
        sort(vp.begin(), vp.end(), cmp);
        sort(worker.begin(), worker.end(), greater<int>());

        //i is for traversing the vp and j is for traversing the worker
        int i = 0, j = 0;

        while(i<vp.size() and j<worker.size()){
            if(worker[j]>=vp[i].second){
                ans+=vp[i].first;
                j++;
            }
            else{
                i++;
            }
        }

        return ans;
    }
};
var maxProfitAssignment = function(difficulty, profit, worker) {
    const data = [];

    for (let i = 0; i < difficulty.length; i++) {
        data.push({ difficulty: difficulty[i], profit: profit[i] });
    }

    data.sort((a, b) => a.difficulty - b.difficulty);

    let maxProfit = 0;

    for (let i = 0; i < data.length; i++) {
        data[i].profit = maxProfit = Math.max(maxProfit, data[i].profit);
    }

    // worker.sort((a, b) => a - b);

    let ans = 0;
    let min = 0;

    for (const skill of worker) {
        let left = 0; // min;
        let right = data.length - 1;

        while (left < right) {
            const mid = Math.floor((left + right + 1) / 2);

            if (data[mid].difficulty > skill) {
                right = mid - 1;
            } else {
                left = mid;
            }
        }

        if (data[left].difficulty > skill) {
            continue;
        }

        // min = left;
        ans += data[left].profit;
    }

    return ans;
};
Most Profit Assigning Work