出租车最大盈利

122 阅读2分钟

问题描述

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

乘客信息用一个下标从 0 开始的二维数组 rides 表示,其中 rides[i] = [starti, endi, earni] 表示第 i 位乘客需要从地点 starti 前往 endi ,愿意支付 earni 元的费用。你同时 最多 只能接一个订单。

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

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

解决思路

我们需要计算出租车行驶到endi处所累积盈利的最大值p[endi],这个最大值由(p[starti], earni)共同决定。其中,p[starti]代表出租车行驶到starti处所累积盈利的最大值。

编程实现

方法1:存在耗时问题

class Solution:
    def maxTaxiEarnings(self, n: int, rides: List[List[int]]) -> int:
        ret = 0
        rides.sort(key = lambda x:x[1])
        p = [0] * (n + 1)
        for start, end, bonus in rides:
            for pre_start in range(start, -1, -1):
                p[end] = max(p[end], bonus + p[pre_start])
            ret = max(ret,p[end])
        return ret

方法2: 解决耗时问题

class Solution:
    def maxTaxiEarnings(self, n: int, rides: List[List[int]]) -> int:
        d = defaultdict(list)
        for x in rides:
            d[x[1]].append(x)
            
        dp = [0] * (n + 1)
        
        for e in range(1, n + 1):
            dp[e] = dp[e -1] # 兜底,很重要
            for aa, _, cc in d[e]:
                dp[e] = max(dp[e], dp[aa] + cc)
                
        return dp[-1]

问题延展

这个问题可以扩展到一般情况,比如一个人在一天中有许多任务,每一个任务有起始、结束时间以及对应的奖励值。他需要通过合理安排任务去获得最大的奖励。当然,一次最多只能做一个任务。输入数据就是[[start0,end0,bonus0],...[starti,endi,bonusi],...]。这种问题就可以利用上面的方法计算出最大值。

leetcode类似题目

-435. 无重叠区间

-1235. 规划兼职工作

-1751. 最多可以参加的会议数目 II

-2008. 出租车的最大盈利

-2054. 两个最好的不重叠活动

-2830. 销售利润最大化