2023-07-25:你驾驶出租车行驶在一条有 n 个地点的路上 这 n 个地点从近到远编号为 1 到 n ,你想要从 1 开到 n 通过接乘客订单盈利。你只能沿着编号递增的方向前进,不能改变方向 乘
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 通过接乘客订单盈利。你只能沿着编号递增的方向前进,不能改变方向 乘的更多相关文章
- XPath语法 在C#中使用XPath示例 【转http://www.cnblogs.com/yukaizhao/archive/2011/07/25/xpath.html】非常详细的文章
		
XPath语法 在C#中使用XPath示例 XPath可以快速定位到Xml中的节点或者属性.XPath语法很简单,但是强大够用,它也是使用xslt的基础知识. 示例Xml: <?xml ve ...
 - 2018.07.25 bzoj2125: 最短路(圆方树+倍增)
		
传送门 人生的第一道仙人掌. 这道题求是仙人掌上的最短路. 先建出圆方树,然后用倍增跑最短路,当lca" role="presentation" style=" ...
 - 2018.07.25 bzoj3878: [Ahoi2014&Jsoi2014]奇怪的计算器(线段树)
		
传送门 线段树综合. 让我想起一道叫做siano" role="presentation" style="position: relative;"&g ...
 - 2018.07.25 hdu5306Gorgeous Sequence(线段树)
		
传送门 线段树基本操作. 要求维护区间取min" role="presentation" style="position: relative;"> ...
 - DolphinScheduler 线上 Meetup 视频回放(07.25)
		
上周六下午 DolphinScheduler 社区联合 Doris 社区进行了 2020 年首次线上 Meetup,各位讲师都做了非常精彩的分享,也吸引了 1900 多位技术伙伴观看. 其中 Dolp ...
 - 2022.07.25 TypeScript基础类型介绍
		
基础类型: 字符串(string)(String) let first: string = 'niu' // 直接赋值 let fourth: string = `niu` // 模板字符串 let ...
 - BUAA面向对象设计与构造——第二单元总结
		
BUAA面向对象设计与构造——第二单元总结 第一阶段:单部傻瓜电梯的调度 第二阶段:单部可捎带电梯的调度 (由于我第一次写的作业就是可捎带模式,第二次只是增加了负数楼层,修改了一部分参数,因此一起总结 ...
 - OO第三阶段作业总结
		
调研: 最早的程序设计是直接采用机器语言来编写的,或者使用二进制码来表示机器能够识别和执行的指令和数据.机器语言的优点在于速度快,缺点在于写起来实在是太困难了,编程效率低,可读性差,并且 ...
 - TSR交通标志检测与识别
		
TSR交通标志检测与识别 说明: 传统图像处理算法的TSR集成在在ARM+DSP上运行,深度学习开发的TSR集成到FPGA上运行. 输入输出接口 Input: (1)图像视频分辨率(整型int) (2 ...
 - liunx驱动----USB驱动
		
现象:把usb设备接入电脑 1.Windows发现设备 2.跳出一个对话框提示安装驱动程序 问1:既然没有驱动程序,为什么了够知道是什么驱动了?? 答1:Windows里面已经有了usb总线驱动程序, ...
 
随机推荐
- C++ Primer 5th 阅读笔记:变量和基本类型
			
一些语言的公共特性 内建类型,如整型,字符型等: 变量,为值绑定的一个名字: 表达式和语句,操作值. 分支和循环,允许我们条件执行和重复执行: 函数,定义抽象计算单元. 扩展语言的方式 自定义类型: ...
 - LeetCode 周赛 344(2023/05/07)手写递归函数的固定套路
			
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问. 大家好,我是小彭. 今天下午有力扣杯战队赛,不知道官方是不是故意调低早上周赛难度给选手们练练手. 往期周赛回 ...
 - NUXT3.0实现网络请求二次封装
			
最近在开发基于nuxt3.0的项目,看了官网的网络请求,感觉不太适合,就自己基于官网的useFetch()方法封装了一个网络请求,下面开始实现封装. 第一步:新建http.ts文件,用于编写封装代码 ...
 - vue全家桶进阶之路1:前言
			
Vue.js简称Vue,用于构建用户界面的渐进式框架. Vue是一款国产前端框架,它的作者尤雨溪(Evan You)是一位美籍华人,2014年2月,尤雨溪开源了一个前端开发库 Vue.js,2015年 ...
 - ModuleNotFoundError: No module named 'flask_sqlalchemy'
			
ModuleNotFoundError: No module named 'flask_sqlalchemy' 解决: pip install flask_sqlalchemy
 - pywin32和wmi的安装和测试
			
E:\pyAPP\Madking\MadKingClient>python bin\NedStark.py collect_dataE:\pyAPP\Madking\MadKingClientT ...
 - 时间函数strftime和strptime的差别
			
strftime是转换为特定格式输出, strptime是将一个时间字符串解析为时间类型对象. strftime是按照想要的格式,去转换.重点是格式! strptime不管什么格式,只要把特定的时间字 ...
 - 【GiraKoo】CMake提示could not find any instance of Visual Studio
			
CMake提示could not find any instance of Visual Studio. 原因 此种情况是由于默认的CMake工具不是Visual Studio提供的版本导致的. 解决 ...
 - cookie和session以及token
			
cookie和seesion以及token 技术都基于状态保持, cookie:  有服务器生成, 以 k:v 形式保持在浏览器端,下次请求服务器,附带cookie信息:存在恶意修改可能:可以对co ...
 - 在国内用Java代理调用OpenAI的ChatGPT的API接口
			
第一步:一个科学友好的上网工具,开启全局代理: 第二步:一个注册好的ChatGPT账号,且在个人设置里面生成apiKey:https://platform.openai.com/account/api ...