2008. 出租车的最大盈利

题目描述

你驾驶出租车行驶在一条有 n个地点的路上。这 n个地点从近到远编号为 1n,你想要从 1开到 n,通过接乘客订单盈利。你只能沿着编号递增的方向前进,不能改变方向。

乘客信息用一个下标从 0开始的二维数组 rides表示,其中 rides[i] = [starti, endi, tipi]表示第 i位乘客需要从地点 starti前往 endi,愿意支付 tipi元的小费。

每一位你选择接单的乘客 i,你可以盈利 endi - starti + tipi元。你同时最多只能接一个订单。

给你 nrides,请你返回在最优接单方案下,你能盈利最多多少元。

注意:你可以在一个地点放下一位乘客,并在同一个地点接上另一位乘客。

做题情况

  1. 做出来且思路与标答一致
  2. 做出来但思路较为复杂
  3. 有思路,但时间复杂度较高无法通过
  4. 没有思路 ☑

自己的想法:

自己其实是有一些思路的,但是不是很多,自己知道应该用动态规划来解,不过可能确实有点问题,自己没有绕过来,即使告诉自己怎么做,自己得到这个解的可行性还是需要一定时间。
总结了一下,可能存在这样的问题:
1.二分法真的是自己的短板。
2.这类题的动态规划自己掌握的不是很好。

标答:动态规划+二分法

这个题有几个需要注意的问题:
1.排序要按照结束时间的顺序来。这一点是从贪心得到的思路,结束时间早才是真的早,且开始时间一定是早于结束时间的,这相当于既限制了开始时间,又限制了结束时间。
2.动态规划。我们设置的是可以取开始到当前这些客人所取到的最大值。在进行循环更新时,我们会回到可以放的下当前客人的最晚位置。这个地方的可行性自己绕了很久才明白(之前自己也有一个题绕了很久也不明白,也许这两道题之间存在联系)。首先这个位置之后一定是不能和当前客人同时取到的,即使他们接送那个位置的客人,也是会回到最晚位置之前的。最晚位置一定可以取到当前客人,且比前面的值一定大。
如果不取当前的客人,那么就直接等于前面一个的最大值就可以了。
这个明天自己再想一下吧,感觉是自己之前所没有想过的问题。
3.二分法。这个自己是真的不熟,很多时候就是因为没有想到二分法导致自己没有想出来。n*logn的复杂度自己一定要想一下二分法,别只惦记着排序这类东西了。

实际代码

class Solution {
public:
    struct Ride
    {
        int start;
        int end;
        int tip;
        Ride(){}
        Ride(int a,int b,int c)
        {
            start=a;
            end=b;
            tip=c;
        }
        bool operator < (const Ride& other) const
        {
            if (end!=other.end) return end<other.end;
            else if (start!=other.start) return start<other.start;
            else return tip>other.tip;
        }
    };
    static bool cmp(int x,const Ride& ride)
    {
        return x<ride.end;
    }
    long long maxTaxiEarnings(int n, vector<vector<int>>& rides) 
    {
        //第一想法是动态规划,其实可以按照结束时间来排序的
        //想了一下应该是可行的,先结束时间排序,再把每一个都放入到优先队列里面
        int m=rides.size();
        vector<Ride> vec(m);
        for (int i=0;i<rides.size();++i)
        {
            vec[i]=Ride(rides[i][0],rides[i][1],rides[i][2]);
        }
        sort(vec.begin(),vec.end());
        vector<long long> dp(m+1,0);
        for (int i=0;i<m;++i)
        {
            int j=upper_bound(vec.begin(),vec.begin()+i,vec[i].start,cmp)-vec.begin();
            dp[i+1]=max(dp[i],dp[j]+vec[i].end-vec[i].start+vec[i].tip);
        }
        return dp[m];
    }
};

总结

这个题还是很值得好好想一下的,这些有多个维度的题,自己总是有点问题,之后再多想一点!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值