【每日一题】出租车的最大盈利

文章目录

  • Tag
  • 题目来源
  • 解题思路
    • 方法一:递归
    • 方法二:递归+记录数组=记忆化搜索
    • 方法三:动态规划(递推)
  • 写在最后

Tag

【递归】【记忆化搜索】【动态规划】【数组】【2023-12-08】


题目来源

2008. 出租车的最大盈利


解题思路

以下题解与思路参考 教你一步步思考动态规划:从记忆化搜索到递推(Python/Java/C++/Go/JS/Rust)。

寻找子问题

假设 n = 9。我们要解决的问题是从 1 开车到 9 最多可以赚多钱。

会有以下两种情况出现:

  • 情况一:如果没有乘客在 9 下车,或者我们不搭载在 9 下车的乘客,那么问题就变成:从 1 开车到 8 最多可以赚多少钱;
  • 情况二:如果有至少一位乘客在 9 下车,我们可以枚举载哪位乘客。假设所载乘客在 5 上车,那么从 5 到 9 不能载其它乘客(题目要求同时最多只能接一个订单),问题变成:从 1 到 5 最多可以赚多少钱。

以上两种情况都会将原问题变成 「和原问题相似的、规模更小的子问题」,这意味着可以使用递归来解决问题。

方法一:递归

思路

递归函数定义为 dfs(i),表示从 1 开车到 i 最多可以赚多少钱。

情况一中问题变为:从 1 开车到 i-1 最多可以赚钱多少,有转移关系式:

d f s ( i ) = d f s ( i − 1 ) dfs(i) = dfs(i - 1) dfs(i)=dfs(i1)

在情况二中,我们可以枚举搭载哪位乘客,取其中最赚钱的方案,有转移关系式:

d f s ( i ) = m a x ( d f s ( s t a r t ) + i − s t a r t + t i p ) dfs(i) = max(dfs(start) + i - start + tip) dfs(i)=max(dfs(start)+istart+tip)
其中,start 表示到 i 的乘客的上车点,tip 为从 start 到 i 这一段路的小费。

以上两种情况取最大值得到 dfs(i),即

d f s ( i ) = m a x ( d f s ( i − 1 ) , m a x ( d f s ( s t a r t ) + i − s t a r t + t i p ) ) dfs(i) = max(dfs(i - 1), max(dfs(start) + i - start + tip)) dfs(i)=max(dfs(i1),max(dfs(start)+istart+tip))

递归边界:dfs(1) = 0,因为没有在 1 下车的乘客。

递归入口:dfs(n),也是最后需要返回的答案。

算法

在实现中,将 rides 数组按照下车点进行分组,方便枚举所有在 i 下车点下车的乘客。在分组中,使用 pair 记录每一个分组中的 startend - start + tip

class Solution {
public:long long maxTaxiEarnings(int n, vector<vector<int>>& rides) {vector<vector<pair<int, int>>> g(n+1);for (auto ride : rides) {int start = ride[0], end = ride[1], tip = ride[2];g[end].push_back(make_pair(start, end - start + tip));}function<long long(int)> dfs = [&](int i) -> long long {if (i == 0) {return 0;}long long res = dfs(i - 1);for (auto [s, t] : g[i]) {res = max(res, dfs(s) + t);}return res;};return dfs(n);}
};

该方法超时。

方法二:递归+记录数组=记忆化搜索

思路

由于在递归中存在某些 dfs(i) 重复计算的问题,因此可以使用一个数组 memo 记录计算结果,在递归中使用数据记录计算出的值的方法被称为「记忆化搜索」。

算法

class Solution {
public:long long maxTaxiEarnings(int n, vector<vector<int>>& rides) {vector<vector<pair<int, int>>> g(n+1);for (auto ride : rides) {int start = ride[0], end = ride[1], tip = ride[2];g[end].push_back(make_pair(start, end - start + tip));}vector<long long> memo(n+1, -1);    // -1 表示没有计算过function<long long(int)> dfs = [&](int i) -> long long {if (i == 0) {return 0;}auto& res = memo[i];    // 这里是引用,因为后面需要将更新后的 res 更新到 memo 中if (res != -1) {return res;}res = dfs(i - 1);for (auto [s, t] : g[i]) {res = max(res, dfs(s) + t);}return res;};return dfs(n);}
};

复杂度分析

时间复杂度: O ( n + m ) O(n+m) O(n+m)

空间复杂度: O ( n + m ) O(n+m) O(n+m)

方法三:动态规划(递推)

思路

将递归对应翻译为动态规划。

状态方程 f[i] 表示从 1 开车到 i 最多可以赚多少钱。

状态转移关系:

f [ i ] = m a x ( f [ i − 1 ] , m a x ( f [ s t a r t ] + i − e n d + t i p ) ) f[i] = max(f[i-1], max(f[start] + i - end + tip)) f[i]=max(f[i1],max(f[start]+iend+tip))

base case:f[1] = 0。

最后返回:return f[n]。

算法

class Solution {
public:long long maxTaxiEarnings(int n, vector<vector<int>>& rides) {vector<vector<pair<int, int>>> g(n+1);for (auto ride : rides) {int start = ride[0], end = ride[1], tip = ride[2];g[end].push_back(make_pair(start, end - start + tip));}vector<long long> f(n+1);    for (int i = 2; i <= n; ++i) {f[i] = f[i-1];for (auto [s, t] : g[i]) {f[i] = max(f[i], f[s] + t);}}return f[n];}
};

复杂度分析

时间复杂度: O ( n + m ) O(n+m) O(n+m),其中 m m mrides 的长度,n 是地点数目。动态规划转移需要 O ( n ) O(n) O(n) 的时间,查询乘客信息需要 O ( m ) O(m) O(m) 的时间。

空间复杂度: O ( n + m ) O(n+m) O(n+m)


写在最后

如果您发现文章有任何错误或者对文章有任何疑问,欢迎私信博主或者在评论区指出 💬💬💬。

如果大家有更优的时间、空间复杂度的方法,欢迎评论区交流。

最后,感谢您的阅读,如果有所收获的话可以给我点一个 👍 哦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/206715.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【EI会议征稿中】2024年第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)

2024年第四届人工智能、自动化与高性能计算国际会议&#xff08;AIAHPC 2024&#xff09; 2024 4th International Conference on Artificial Intelligence, Automation and High Performance Computing 2024第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)将于20…

游戏被攻击怎么办

随着科技的进步和互联网的普及&#xff0c;游戏行业也正在经历前所未有的变革。玩家们不再满足于传统的线下游戏&#xff0c;而是转向了线上游戏。然而&#xff0c;随着游戏的线上化&#xff0c;游戏安全问题也日益凸显。游戏受到攻击是游戏开发者永远的痛点&#xff0c;谈“D“…

HomeAssistant添加HACS插件并实现公网控制米家,HomeKit等智能家居

HomeAssistant添加HACS插件并实现公网控制米家&#xff0c;HomeKit等智能家居 文章目录 HomeAssistant添加HACS插件并实现公网控制米家&#xff0c;HomeKit等智能家居基本条件一、下载HACS源码二、添加HACS集成三、绑定米家设备 ​ 上文介绍了如何实现群晖Docker部署HomeAssist…

SQLserver截取字符串

当我们存的数据是json的时候可以全部取出在模糊查询但是有多个重复数据的时候就没办法准确的模糊出来这个时候我们就需要用的字符串截取 --创建函数create FUNCTION [dbo].[Fmax] (str varchar(50),start VARCHAR(50),length VARCHAR(50)) RETURNS varchar(max) AS BEGINDEC…

条码生成器与Zint使用

文章目录 目的条形码zint支持条形码种类下载编译qt pro配置code保存条形码目的 1: 了解条形码数据理论知识 2: 了解zint第三方库相关, 如何编译引用到项目中 条形码 条形码(Barcode)一维码 和二维码(QR code)都是用于存储信息的图形化表示方式,通常应用于商品标识、库…

无头浏览器与Selenium:探索无界爬虫的奇妙世界

selenium设置无头浏览器 背景 ​ 我们之前的selenium都是浏览器驱动自动打开一个网页&#xff0c;执行相关操作&#xff0c;其实也可以让其后台显示&#xff0c;不用在前台显示。 ​ 要设置无头浏览器&#xff0c;可以使用Selenium的Headless模式。在Headless模式下&#xf…

Kafka中的Topic

在Kafka中&#xff0c;Topic是消息的逻辑容器&#xff0c;用于组织和分类消息。本文将深入探讨Kafka Topic的各个方面&#xff0c;包括创建、配置、生产者和消费者&#xff0c;以及一些实际应用中的示例代码。 1. 介绍 在Kafka中&#xff0c;Topic是消息的逻辑通道&#xff0…

【华为数据之道学习笔记】3-2 基础数据治理

基础数据用于对其他数据进行分类&#xff0c;在业界也称作参考数据。基础数据通常是静态的&#xff08;如国家、币种&#xff09;&#xff0c;一般在业务事件发生之前就已经预先定义。它的可选值数量有限&#xff0c;可以用作业务或IT的开关和判断条件。当基础数据的取值发生变…

基于OpenCV+CNN+IOT+微信小程序智能果实采摘指导系统——深度学习算法应用(含pytho、JS工程源码)+数据集+模型(五)

目录 前言总体设计系统整体结构图系统流程图 运行环境Python环境TensorFlow 环境Jupyter Notebook环境Pycharm 环境微信开发者工具OneNET云平台 模块实现1. 数据预处理2. 创建模型并编译3. 模型训练及保存4. 上传结果5. 小程序开发1&#xff09;查询图片2&#xff09;查询识别结…

paypal贝宝怎么绑卡支付

一、PayPal是什么 PayPal是一个很多国家地区通用的支付渠道&#xff0c;我们可以把它理解为一项在线服务&#xff0c;相当于美国版的支付宝。你可以通过PayPal进行汇款和收款&#xff0c;相比传统的电汇和西联那类的汇款方式&#xff0c;PayPal更加简单和容易&#xff0c;被很…

利用proteus实现串口助手和arduino Mega 2560的串口通信

本例用到的proteus版本为8.13&#xff0c;ardunio IDE版本为2.2.1&#xff0c;虚拟串口vspd版本为7.2&#xff0c;串口助手SSCOM V5.13.1。软件的下载安装有很多教程&#xff0c;大家可以自行搜索&#xff0c;本文只介绍如何利用这4种软件在proteus中实现arduino Mega 2560的串…

刷题记录--算法--简单

第一题 2582. 递枕头 已解答 简单 相关标签 相关企业 提示 n 个人站成一排&#xff0c;按从 1 到 n 编号。 最初&#xff0c;排在队首的第一个人拿着一个枕头。每秒钟&#xff0c;拿着枕头的人会将枕头传递给队伍中的下一个人。一旦枕头到达队首或队尾&#xff0c;传递…

高防IP是什么?有什么优势?

随着互联网的普及和快速发展&#xff0c;网络安全问题日益突出。在众多安全问题中&#xff0c;DDOS攻击是一种常见的攻击手段&#xff0c;它通过发送大量的无效或低效请求&#xff0c;使得目标服务器无法响应正常用户的请求&#xff0c;从而造成服务不可用的情况。为了解决这个…

如何使用eXtplorer+cpolar内网穿透搭建个人云存储实现公网访问

文章目录 1. 前言2. eXtplorer网站搭建2.1 eXtplorer下载和安装2.2 eXtplorer网页测试2.3 cpolar的安装和注册 3.本地网页发布3.1.Cpolar云端设置3.2.Cpolar本地设置 4.公网访问测试5.结语 1. 前言 通过互联网传输文件&#xff0c;是互联网最重要的应用之一&#xff0c;无论是…

PHP escapeshellarg()+escapeshellcmd()绕过

文章目录 函数利用escapeshellarg()函数escapeshellcmd()函数 exp执行原理攻击面例题 [BUUCTF 2018]Online Tool例题 [网鼎杯 2020 朱雀组]Nmap 函数利用 escapeshellarg()函数 单引号 ()&#xff1a;转义为 \。 双引号 (")&#xff1a;转义为 \"。 反斜杠 (\)&…

专业130+总分400+云南大学通信847专业基础综考研经验(原专业课827)

今年专业130总分400云南大学通信上岸&#xff0c;整体考研感觉还是比较满意&#xff0c;期间也付出了很多心血&#xff0c;走过弯路&#xff0c;下面分享一下这一年考研得失&#xff0c;希望大家可以从中有所借鉴。 先说明我在考研报名前更换成云南大学的理由&#xff1a;&…

谷歌正式发布最强 AI 模型 Gemini

2023年12月6日&#xff0c;谷歌公司宣布推出其被认为是规模最大、功能最强大的人工智能模型 Gemini。 Gemini将分为三个不同的套件&#xff1a;Gemini Ultra、Gemini Pro和Gemini Nano。 Gemini Ultra被认为具备最强大的能力&#xff0c;Gemini Pro则可扩展至多任务&#x…

xilinx原语详解及仿真——ODDR

ODDR位于OLOGIC中&#xff0c;可以把单沿传输的数据转换为双沿传输的数据&#xff0c; 在讲解ODDR功能之前&#xff0c;需要先了解OLOGIC的结构及功能。 1、OLOGIC OLOGIC块位于IOB的内侧&#xff0c;FPGA内部信号想要输出到管脚&#xff0c;都必须经过OLOGIC。OLOGIC资源的类…

CleanMyMac4.16中文最新版本下载

当很多人还在为电脑运行缓慢、工作问题不能快速得到解决而烦恼的时候&#xff0c;我已经使用过了多款系统清理工具&#xff0c;并找到了最适合我的那一款。我的电脑是超耐用的Mac book&#xff0c;接下来给大家介绍三种在众多苹果电脑清理软件的排名较高的软件。 一、Maintena…

NVIDIA与 Sparkfun 的合作伙伴在 Hackster.io 上发起了人工智能创新挑战赛,喊你来参加!

NVIDIA与 Sparkfun 的合作伙伴在 Hackster.io 上发起了人工智能创新挑战赛&#xff0c;喊你来参加&#xff01; 本次竞赛的目标旨在吸引开发者社区在 NVIDIA Jetson Orin 平台上为边缘构建生成式 AI 应用程序和模型&#xff0c;希望通过本次比赛提高人们对新 Jetson 生成式 AI…