LeetCode 1235. Maximum Profit in Job Scheduling DP 二分

231 篇文章 0 订阅
120 篇文章 1 订阅

We have n jobs, where every job is scheduled to be done from startTime[i] to endTime[i], obtaining a profit of profit[i].

You're given the startTime , endTime and profit arrays, you need to output the maximum profit you can take such that there are no 2 jobs in the subset with overlapping time range.

If you choose a job that ends at time X you will be able to start another job that starts at time X.

 

Example 1:

Input: startTime = [1,2,3,3], endTime = [3,4,5,6], profit = [50,10,40,70]
Output: 120
Explanation: The subset chosen is the first and fourth job. 
Time range [1-3]+[3-6] , we get profit of 120 = 50 + 70.

Example 2:


Input: startTime = [1,2,3,4,6], endTime = [3,5,10,6,9], profit = [20,20,100,70,60]
Output: 150
Explanation: The subset chosen is the first, fourth and fifth job. 
Profit obtained 150 = 20 + 70 + 60.

Example 3:

Input: startTime = [1,1,1], endTime = [2,3,4], profit = [5,6,4]
Output: 6

 

Constraints:

  • 1 <= startTime.length == endTime.length == profit.length <= 5 * 10^4
  • 1 <= startTime[i] < endTime[i] <= 10^9
  • 1 <= profit[i] <= 10^4

---------------------------------------------------------

Some tips:

  • It's easy to come up with DP, f[i][j]=max(f[i-1][j-range]+profit,f[i-1][j]),but use binary tuple to store the results
  • Binary search to find the last <= target, e.g., upper_bound-1
class Solution:
    def jobScheduling(self, startTime, endTime, profit) -> int:
        def upper_bound(lst, tgt):
            l,r = 0,len(lst)-1
            while (l <= r):
                mid = l + ((r-l)>>1)
                if (lst[mid][0] > tgt):
                    r = mid-1
                else:
                    l = mid+1
            return l

        end_list = [[0,0]] #[endtime, accu_profit]
        res = profit[0]

        for et,st,pro in sorted(list(zip(endTime, startTime, profit))):
            base = end_list.pop() if (end_list and end_list[-1][0] == et) else [et, 0]
            pos = upper_bound(end_list, st)-1 #The last <= target
            pre = end_list[pos][1]
            if (pre+pro > base[1]):
                base[1] = max(pre+pro, end_list[-1][1])
            res = max(res, base[1])
            end_list.append(base)
            #print("end_list={0} st={1}".format(end_list, st))
        return res
s = Solution()
print(s.jobScheduling(startTime = [1,2,3,3], endTime = [3,4,5,6], profit = [50,10,40,70]))

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值