首页 > 其他分享 >Leetcode 1235. 规划兼职工作

Leetcode 1235. 规划兼职工作

时间:2024-09-28 10:01:35浏览次数:6  
标签:1235 工作 profit int startTime 兼职 endTime Leetcode dp

1.题目基本信息

1.1.题目描述

你打算利用空闲时间来做兼职工作赚些零花钱。

这里有 n 份兼职工作,每份工作预计从 startTime[i] 开始到 endTime[i] 结束,报酬为 profit[i]。

给你一份兼职工作表,包含开始时间 startTime,结束时间 endTime 和预计报酬 profit 三个数组,请你计算并返回可以获得的最大报酬。

注意,时间上出现重叠的 2 份工作不能同时进行。

如果你选择的工作在时间 X 结束,那么你可以立刻进行在时间 X 开始的下一份工作。

1.2.题目地址

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

2.解题方法

2.1.解题思路

动态规划+二分查找

2.2.解题步骤

第一步,状态定义;dp[i]为前i个兼职工作的最大报酬

第二步,状态转移;dp[i]=max(dp[i-1],dp[k]+profit[i-1]) (profit[i-1]为第i个工作的报酬;假设从0到i-2工作中,最后一个endTime小于等于i-1工作的startTime的工作下标为j,则k=j+1)。这里使用左闭右闭的未标记区间的方式进行二分

3.解题代码

Python代码

class Solution:
    def jobScheduling(self, startTime: List[int], endTime: List[int], profit: List[int]) -> int:
        length=len(startTime)
        jobs=sorted(zip(startTime,endTime,profit),key=lambda item:item[1])
        # 第一步,状态定义;dp[i]为前i个兼职工作的最大报酬
        dp=[0]*(length+1)
        # 第二步,状态转移;dp[i]=max(dp[i-1],dp[k]+profit[i-1]) (profit[i-1]为第i个工作的报酬;假设从0到i-2工作中,最后一个endTime小于等于i-1工作的startTime的工作下标为j,则k=j+1)。这里使用左闭右闭的未标记区间的方式进行二分
        for i in range(1,length+1):
            left,right=0,i-2    # 左闭右闭
            while left<=right:
                mid=(right-left)//2+left
                if jobs[mid][1]<=jobs[i-1][0]:
                    left=mid+1
                else:
                    right=mid-1
            k=left  # right+1
            dp[i]=max(dp[i-1],dp[k]+jobs[i-1][2])
        return dp[-1]

C++代码

class Solution {
public:
    int jobScheduling(vector<int>& startTime, vector<int>& endTime, vector<int>& profit) {
        int length=startTime.size();
        vector<vector<int>> jobs(length);
        for(int i=0;i<length;++i){
            jobs[i]={startTime[i],endTime[i],profit[i]};
        }
        sort(jobs.begin(),jobs.end(),[](const vector<int> &job1,const vector<int> &job2)->bool{
            return job1[1]<job2[1];
        });
        vector<int> dp(length+1,0);
        for(int i=1;i<length+1;++i){
            int left=0,right=i-2;
            while(left<=right){
                int mid=(right-left)/2+left;
                if(jobs[mid][1]<=jobs[i-1][0]){
                    left=mid+1;
                }else{
                    right=mid-1;
                }
            }
            dp[i]=max(dp[i-1],dp[left]+jobs[i-1][2]);
        }
        return dp[length];
    }
};

4.执行结果

在这里插入图片描述

标签:1235,工作,profit,int,startTime,兼职,endTime,Leetcode,dp
From: https://www.cnblogs.com/geek0070/p/18437052

相关文章

  • Leetcode面试经典150题-64.最小路径和
    给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。说明:每次只能向下或者向右移动一步。示例1:输入:grid=[[1,3,1],[1,5,1],[4,2,1]]输出:7解释:因为路径1→3→1→1→1的总和最小。示例2:输入:grid=[[1......
  • LeetCode--Dota2 参议院(day 2)
     今天给大家带来LeetCode中的一道算法题:参议院问题,忘记具体内容的朋友可以观看下图: 根据题意,我们可以清楚的认识到获胜条件:那就是字符串中仅包含D或R。 我们先以RDRDD为例进行说明: 字符串中的第一个R行使权力,淘汰D阵营中的某一位,我们可以看见字符串中有三个D,那么该......
  • leetCode--爬楼梯(记录做题过程加深印象)
    首先最广泛的方法为递归,直接上代码:intclimbStairs(intn){if(n==1){return1;}if(n==2){return2;}if(flag[n])returnflag[n];returnflag[n]=climbStairs(n-1)+climbStair......
  • 【算法题】72. 编辑距离-力扣(LeetCode)
    【算法题】72.编辑距离-力扣(LeetCode)1.题目下方是力扣官方题目的地址72.编辑距离给你两个单词word1和word2,请返回将word1转换成word2所使用的最少操作数。你可以对一个单词进行如下三种操作:插入一个字符删除一个字符替换一个字符示例1:输入:word1="ho......
  • 875. 爱吃香蕉的珂珂(leetcode)
    https://leetcode.cn/problems/koko-eating-bananas/description/二段性:速度有得完和不吃完两个段关键点是编写check函数,比较繁杂classSolution{publicintminEatingSpeed(int[]piles,inth){intsum=0;intmax=0;for(inti=0;i<piles.......
  • Leetcode 154. 寻找旋转排序数组中的最小值 II
    1.题目基本信息1.1.题目描述已知一个长度为n的数组,预先按照升序排列,经由1到n次旋转后,得到输入数组。例如,原数组nums=[0,1,4,4,5,6,7]在变化后可能得到:若旋转4次,则可以得到[4,5,6,7,0,1,4]若旋转7次,则可以得到[0,1,4,4,5,6,7]注意,数组[a[0],a[1],a[2],......
  • 【LeetCode Hot 100】21. 合并两个有序链表
    题目描述最简单粗暴的想法是将两个链表的所有元素拿出来放在一个数组中,再将此数组排序,最后生成一个新链表并返回。由于给出的参数本身就是两个排好序的链表,可以进行一次遍历,就能保证元素仍然是有序的:每次比较当前指针指向的两个元素的大小,较小的拿出来作为当前元素并将指针向前移......
  • LeetCode刷题日记之二叉树(二)
    目录前言左叶子之和找树左小角的值总结前言经过数模比赛的四天忙碌后博主继续开始LeetCode学习了,给大家分享学习心路的同时也是在不断勉励自己每天把自己的学的东西去进行一个产出记录,不足的地方欢迎大家批评指正,一起加油吧朋友们!......
  • 410. 分割数组的最大值(leetcode)
    https://leetcode.cn/problems/split-array-largest-sum/description/比较难的二分,关键点在于看出二段性,段数越多最大值越小,段数越小最大值越大,二分最大值,然后就是最大值的合法性校验(判断段数<=k),用于二分的checkclassSolution{publicintsplitArray(int[]n......
  • 【leetcode】2. 两数相加
      总体思路:1.将两个链表里的数字相加:总左往右加,存入第三方链表L3里;2.设置一个进位符t,用来存储每位相加的进位信息;3.对多出来单独的链表进行处理(只需考虑进位),接入到L3的后面。/***Definitionforsingly-linkedlist.*structListNode{*intval;*s......