leetcode1235. 规划兼职工作

1235. 规划兼职工作

动态规划dp
d p [ i ] = m a x ( d p [ i − 1 ] , d p [ k ] + p r o f i t [ i − 1 ] ) dp[i]=max(dp[i−1],dp[k]+profit[i−1]) dp[i]=max(dp[i1],dp[k]+profit[i1])
其中 k 表示满足结束时间小于等于第 i - 1 份工作开始时间的兼职工作数量,可以通过二分查找获得。

注意:dp不仅仅可以使用时间作为i,也可以使用项目序号作为i。例如本题使用了工作的序号作为i。

本题目我卡了很久,因为没有区分清楚dp的i和jobs的i的区别,所以二分查找的时候没有搞清楚。dp是前i个工作,考察的是0~i-1的工作。

二分查找k的时候,希望的工作j应当满足end[j]<=start[i-1]。
下面代码写的二分查找,找到的是第一个大于target的序号。
所以我们找到第一个end>start[i-1]的工作的序号k,,那么0到k-1的所有工作的end都是小于start[i-1]的,所以dp[k](dp[k]考察的是0到k-1的动作)就是做工作i-1之前做的所有工作。

#define MAX(a,b) ((a)>(b)?(a):(b))

int binarySearch(const int jobs[][3],int right, int target){
    int left=0;
    int mid;
    while(left<right){
        mid=(left+right)/2;
        if(jobs[mid][1]>target){
            right=mid;
        }
        else{
            left=mid+1;
        }
    }

    return left;
}
static inline int cmp(const void *pa,const void *pb){
    int* a=(int *)pa;
    int *b=(int *)pb;
    return a[1]-b[1];
}

int jobScheduling(int* startTime, int startTimeSize, int* endTime, int endTimeSize, int* profit, int profitSize){
    int n=startTimeSize;
    int jobs[n][3];
    for(int i=0;i<n;i++){
        jobs[i][0]=startTime[i];
        jobs[i][1]=endTime[i];
        jobs[i][2]=profit[i];
    }
    qsort(jobs,n,sizeof(jobs[0]),cmp);

    int dp[n+1];
     memset(dp, 0, sizeof(dp));
    for(int i=1;i<=n;i++){
        int k=binarySearch(jobs,i-1,jobs[i-1][0]);
        dp[i]=MAX(dp[i-1],dp[k]+jobs[i-1][2]);
    }
    return dp[n];
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值