🤯1235 max profit in job scheduling

https://leetcode.com/problems/maximum-profit-in-job-scheduling/

理解题意,大概就是你尽可能安排job,但是不一定所有job都要安排上,找出一种安排使得利润最大,这里有个暗含的限制条件是一旦你把job按照开始时间sort之后,你最终安排的jobs,第i个位置要么空着要么是第i个job,没有其他可能,理解这一点dp就有思路了

同时注意dp是从最后一个job倒推过来,我怀疑从前往后也是可以的?dp的含义是从第i个位置往后的总的最大利润,具体看注释,同时注意找nextjob的时候要用binary search来防止超时

class Solution {
    int[] dp;
    class Job implements Comparable<Job> {
        int start;
        int end;
        int profit;
        public Job(int s, int e, int p) {
            start = s;
            end = e;
            profit = p;
        }
        @Override
        public int compareTo(Job a) {
            return this.start - a.start;
        }
    }
    public int jobScheduling(int[] startTime, int[] endTime, int[] profit) {
        // you don't have to use all the jobs
        Job[] jobs = new Job[startTime.length];
        for (int i = 0; i < startTime.length; i++) {
            jobs[i] = new Job(startTime[i], endTime[i], profit[i]);
        }
        // sort jobs by starting time
        Arrays.sort(jobs);
        // in the ith position you can either put the ith job or not, you cannot put other job
        // since they start either earlier or later
        // dp[i] is the max profit from the ith job position to the end you can get
        // there are several situations:
        // 1. you put the ith job in it, and you find other jobs that can be put after it
        // 2. you put the ith job in it, and you find no other jobs that can be put after it
        // 3. you skip this job, don't put the ith job in the ith position
        dp = new int[startTime.length];
        findProfit(jobs);
        return dp[0];
    }
    private void findProfit(Job[] jobs) {
        int n = jobs.length;
        for(int i = n - 1; i >= 0; i--) {
            int profit = 0;
            // find the next job's index that can be put after current job and closest to current job
            // if index is length, then no job can be put after this job
            int nextJob = findNextJob(jobs, jobs[i].end);
            if (nextJob == n) {
                // if we insist on putting this job even though it makes no job being able to put after it
                // the max profit from this job on we get is just the profit of this job
                profit = jobs[i].profit;
            } else {
                profit = jobs[i].profit + dp[nextJob];
            }
            
            if (i == n - 1) {
                //we start from position = n which is our base case 
                // because when there are no more jobs to schedule the maximum profit must be 0
                dp[i] = profit;
            } else {
                // if we make more profit not putting this job, we don't put it, just skip ith
                dp[i] = Math.max(dp[i + 1], profit);
            }
        }
    }
    private int findNextJob(Job[] jobs, int end) {
        int n = jobs.length;
        int l = 0;
        int r = n - 1;
        while (l + 1 < r) {
            int m = l + (r - l) / 2;
            if (jobs[m].start >= end) {
                r = m;
            } else {
                l = m;
            }
        }
        if (jobs[l].start >= end) return l;
        if (jobs[r].start >= end) return r;
        return n;
    }
}

Last updated