问题描述
你驾驶出租车行驶在一条有 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. 销售利润最大化