2023-07-25:你驾驶出租车行驶在一条有 n 个地点的路上

这 n 个地点从近到远编号为 1 到 n ,你想要从 1 开到 n

通过接乘客订单盈利。你只能沿着编号递增的方向前进,不能改变方向

乘客信息用一个下标从 0 开始的二维数组 rides 表示

其中 rides[i] = [starti, endi, tipi]

表示第 i 位乘客需要从地点 starti 前往 endi

愿意支付 tipi 元的小费

每一位 你选择接单的乘客 i ,你可以 盈利 endi - starti + tipi 元

你同时 最多 只能接一个订单。

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

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

输入:n = 5, rides = [[2,5,4],[1,5,1]]。

输出:7。

答案2023-07-25:

maxTaxiEarnings1算法的大体过程如下:

1.对乘客订单rides按照起始地点的编号进行升序排序。

2.调用build函数,构建区间树数据结构,初始化max数组。

3.遍历排序后的rides数组,对每个乘客订单进行处理:

a.根据乘客订单的起始地点,通过maxQuery函数查询当前位置之前的最大盈利额,存储在money变量中。

b.计算当前乘客订单的盈利额,即end-start+tip。

c.将当前乘客订单的结束地点作为索引,更新max数组中对应位置的值,更新为money+当前乘客订单的盈利额。

4.返回maxQuery函数查询整个路程的最大盈利额,即maxQuery(n)。

maxTaxiEarnings2算法的大体过程如下:

1.初始化sorted数组,用于存储所有乘客订单的起始和结束地点,长度为乘客订单数量的两倍。

2.遍历rides数组,将乘客订单的起始和结束地点依次存储到sorted数组中。

3.对sorted数组进行升序排序。

4.对乘客订单rides按照起始地点的编号进行升序排序。

5.初始化dp数组,并将所有元素置为0。

6.初始化dpi变量为0,用于记录当前处理到的sorted数组下标。

7.初始化pre和ans变量为0。

8.遍历排序后的rides数组,对每个乘客订单进行处理:

a.获取当前乘客订单的起始和结束地点。

b.分别使用rank函数查找sorted数组中起始和结束地点的下标。

c.更新dp数组,从dpi到起始地点的下标之间的元素,将其值更新为max(pre, dp[dpi])。

d.计算当前乘客订单的盈利额,即end-start+tip。

e.更新ans变量,取盈利额和当前ans的最大值。

f.将dp数组中结束地点的下标位置的值更新为max(dp[erank], 盈利额)。

9.返回ans变量,即最大盈利额。

这两种算法的核心思想都是通过动态规划来计算每个乘客订单的盈利额,并利用区间树或排序数组来快速查询之前的最大盈利额,从而得到整个路程的最大盈利额。

maxTaxiEarnings1算法的总的时间复杂度为O(nlogn),总的额外空间复杂度为O(n)。

maxTaxiEarnings2算法的总的时间复杂度为O(nlogn),总的额外空间复杂度为O(n)。

go完整代码如下:

package main

import (
"fmt"
"sort"
) const MAXN = 100001 var max = make([]int64, MAXN<<2)
var sorted = make([]int, MAXN)
var dp = make([]int64, MAXN) var n = 0 func build(l, r, rt int) {
if l == r {
max[rt] = 0
} else {
mid := (l + r) / 2
build(l, mid, rt<<1)
build(mid+1, r, rt<<1|1)
pushUp(rt)
}
} func maxQuery(r int) int64 {
if r < 1 {
return 0
}
return maxQueryRange(1, r, 1, n, 1)
} func maxQueryRange(L, R, l, r, rt int) int64 {
if L <= l && r <= R {
return max[rt]
}
mid := (l + r) >> 1
ans := int64(0)
if L <= mid {
ans = max64(ans, maxQueryRange(L, R, l, mid, rt<<1))
}
if R > mid {
ans = max64(ans, maxQueryRange(L, R, mid+1, r, rt<<1|1))
}
return ans
} func update(index int, c int64) {
updateNode(index, c, 1, n, 1)
} func updateNode(index int, c int64, l, r, rt int) {
if l == r {
max[rt] = max64(max[rt], c)
} else {
mid := (l + r) >> 1
if index <= mid {
updateNode(index, c, l, mid, rt<<1)
} else {
updateNode(index, c, mid+1, r, rt<<1|1)
}
pushUp(rt)
}
} func pushUp(rt int) {
max[rt] = max64(max[rt<<1], max[rt<<1|1])
} func maxTaxiEarnings1(len int, rides [][]int) int64 {
sort.Slice(rides, func(i, j int) bool {
return rides[i][0] < rides[j][0]
})
n = len
build(1, n, 1)
for _, ride := range rides {
money := maxQuery(ride[0]) + int64(ride[1]-ride[0]+ride[2])
update(ride[1], money)
}
return maxQuery(n)
} func rank(sorted []int, len int, num int) int {
ans := 0
l := 0
r := len - 1
for l <= r {
m := (l + r) / 2
if sorted[m] >= num {
ans = m
r = m - 1
} else {
l = m + 1
}
}
return ans
} func maxTaxiEarnings2(len0 int, rides [][]int) int64 {
m := len(rides)
j := 0
for i := 0; i < m; i++ {
sorted[j] = rides[i][0]
j++
sorted[j] = rides[i][1]
j++
}
sort.Slice(rides, func(i, j int) bool {
return rides[i][0] < rides[j][0]
})
sort.Ints(sorted[:m<<1])
for i := 0; i < m<<1; i++ {
dp[i] = 0
}
dpi := 0
pre := int64(0)
ans := int64(0)
for _, ride := range rides {
start := ride[0]
end := ride[1]
tips := ride[2]
srank := rank(sorted, m<<1, start)
erank := rank(sorted, m<<1, end)
for dpi <= srank {
pre = max64(pre, dp[dpi])
dpi++
}
money := pre + int64(end-start+tips)
ans = max64(money, ans)
dp[erank] = max64(dp[erank], money)
}
return ans
} func max64(a, b int64) int64 {
if a > b {
return a
}
return b
} func main() {
n := 5
rides := [][]int{{2, 5, 4}, {1, 5, 1}} // n := 20
// rides := [][]int{{1, 6, 1}, {3, 10, 2}, {10, 12, 3}, {11, 12, 2}, {12, 15, 2}, {13, 18, 1}} result1 := maxTaxiEarnings1(n, rides)
result2 := maxTaxiEarnings2(n, rides) fmt.Println("Result from maxTaxiEarnings1:", result1)
fmt.Println("Result from maxTaxiEarnings2:", result2)
}

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

  1. XPath语法 在C#中使用XPath示例 【转http://www.cnblogs.com/yukaizhao/archive/2011/07/25/xpath.html】非常详细的文章

    XPath语法 在C#中使用XPath示例   XPath可以快速定位到Xml中的节点或者属性.XPath语法很简单,但是强大够用,它也是使用xslt的基础知识. 示例Xml: <?xml ve ...

  2. 2018.07.25 bzoj2125: 最短路(圆方树+倍增)

    传送门 人生的第一道仙人掌. 这道题求是仙人掌上的最短路. 先建出圆方树,然后用倍增跑最短路,当lca" role="presentation" style=" ...

  3. 2018.07.25 bzoj3878: [Ahoi2014&Jsoi2014]奇怪的计算器(线段树)

    传送门 线段树综合. 让我想起一道叫做siano" role="presentation" style="position: relative;"&g ...

  4. 2018.07.25 hdu5306Gorgeous Sequence(线段树)

    传送门 线段树基本操作. 要求维护区间取min" role="presentation" style="position: relative;"> ...

  5. DolphinScheduler 线上 Meetup 视频回放(07.25)

    上周六下午 DolphinScheduler 社区联合 Doris 社区进行了 2020 年首次线上 Meetup,各位讲师都做了非常精彩的分享,也吸引了 1900 多位技术伙伴观看. 其中 Dolp ...

  6. 2022.07.25 TypeScript基础类型介绍

    基础类型: 字符串(string)(String) let first: string = 'niu' // 直接赋值 let fourth: string = `niu` // 模板字符串 let ...

  7. BUAA面向对象设计与构造——第二单元总结

    BUAA面向对象设计与构造——第二单元总结 第一阶段:单部傻瓜电梯的调度 第二阶段:单部可捎带电梯的调度 (由于我第一次写的作业就是可捎带模式,第二次只是增加了负数楼层,修改了一部分参数,因此一起总结 ...

  8. OO第三阶段作业总结

    调研:        最早的程序设计是直接采用机器语言来编写的,或者使用二进制码来表示机器能够识别和执行的指令和数据.机器语言的优点在于速度快,缺点在于写起来实在是太困难了,编程效率低,可读性差,并且 ...

  9. TSR交通标志检测与识别

    TSR交通标志检测与识别 说明: 传统图像处理算法的TSR集成在在ARM+DSP上运行,深度学习开发的TSR集成到FPGA上运行. 输入输出接口 Input: (1)图像视频分辨率(整型int) (2 ...

  10. liunx驱动----USB驱动

    现象:把usb设备接入电脑 1.Windows发现设备 2.跳出一个对话框提示安装驱动程序 问1:既然没有驱动程序,为什么了够知道是什么驱动了?? 答1:Windows里面已经有了usb总线驱动程序, ...

随机推荐

  1. 阿里云 AIGC 白嫖 FC 搭建 stable diffusion

    下午瞎逛在 V 站看到阿里在做推广,正好这几天在研究 stable-diffusion,就进去看了看,活动地址: https://developer.aliyun.com/topic/aigc . 主 ...

  2. Python if 语句练习

    if语句 练习 # 1.以特殊方式跟管理员打招呼 # 创建一个至少包含 5 个用户名的列表,且其中一个用户名为 'admin' .想象你要编写代码,在每位用户登录网站后都打印一条问 # 候消息.遍历用 ...

  3. Jmeter-测试报告模板分享

    1.jmeter-results-detail-report_21 <?xml version="1.0"?> <!-- ~ Licensed to the Ap ...

  4. 想打印k8s资源YAML结果搞懂了Client-Side & Server-Side Apply

    前言 由于查看k8s资源YAML时常看到沉长的YAML与手写的格式,相差甚远不利于阅读,经过探索官方文档,才理解什么是Client-Side & Server-Side Apply. 先看一下 ...

  5. 2022-09-23:整数数组 stations 表示 水平数轴 上各个加油站的位置。给你一个整数 k 。 请你在数轴上增设 k 个加油站, 新增加油站可以位于 水平数轴 上的任意位置,而不必放在整数

    2022-09-23:整数数组 stations 表示 水平数轴 上各个加油站的位置.给你一个整数 k . 请你在数轴上增设 k 个加油站, 新增加油站可以位于 水平数轴 上的任意位置,而不必放在整数 ...

  6. 2021-01-10:linux中,我要看某一个进程的并发,通过什么命令去查?

    福哥答案2021-01-10:[答案来自此链接:](https://blog.csdn.net/sinat_31275315/article/details/108239492)方法一:PS在ps命令 ...

  7. 【保姆级教程】如何用Rust编写一个ChatGPT桌面应用

    为什么我们需要一个桌面应用 原因实在太多,我们需要便捷地导出记录,需要在回答长度超长的时候自动加上"继续",需要收藏一些很酷很实用的prompt...... (首先我假设你是一名如 ...

  8. sqlmap的一些简单使用命令

    路径 C:\Users\Administrator\AppData\Local\Programs\Python\Python39\sqlmap post型注入 *每次使用都要重新抓包,不可以使用旧的数 ...

  9. 警惕看不见的重试机制:为什么使用RPC必须考虑幂等性

    0 文章概述 在RPC场景中因为重试或者没有实现幂等机制而导致的重复数据问题,必须引起大家重视,有可能会造成例如一次购买创建多笔订单,一条通知信息被发送多次等问题,这是技术人员必须面对和解决的问题. ...

  10. 代码随想录算法训练营Day18 二叉树|  654.最大二叉树  617.合并二叉树  700.二叉搜索树中的搜索  98.验证二叉搜索树

    654.最大二叉树 题目链接:654.最大二叉树 给定一个不重复的整数数组 nums . 最大二叉树 可以用下面的算法从 nums 递归地构建: 创建一个根节点,其值为 nums 中的最大值. 递归地 ...