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

文章目录

  • 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…

蓝桥杯从零开始备战(Python组)---基础知识篇

第一次尝试报名蓝桥杯的Python组&#xff0c;好好备战&#xff0c;希望省赛可以拿奖&#xff01;目前是整理了一些Python的常用函数和常用内置库&#xff0c;后面可能会开始刷题&#xff0c;如果有比较需要记住的知识点&#xff0c;会再写一篇刷题篇 一、输入输出 1.输入字符…

游戏被攻击怎么办

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

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

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

【嵌入式开发 Linux 常用命令系列 4.1 -- git push 远程分支与本地分支查看】

文章目录 概述git push 语法步骤1&#xff1a;git 远程主机名查看步骤2&#xff1a;git 远程分支名查看步骤3&#xff1a;git 本地分支名查看示例演示 概述 在日常工作中&#xff0c;将代码 git clone 本地之后&#xff0c;或者使用repo init && repo sync 之后不知道…

SQLserver截取字符串

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

商品详情页评论和评论列表评论的排序html代码

以下是一个简单的商品详情页的 HTML 代码示例&#xff1a; <!DOCTYPE html> <html> <head><title>商品详情页</title><style>/* CSS 样式可以在这里添加 */</style> </head> <body><h1>商品详情页</h1><…

7-1 查找书籍

给定n本书的名称和定价&#xff0c;本题要求编写程序&#xff0c;查找并输出其中定价最高和最低的书的名称和定价。 输入格式: 输入第一行给出正整数n&#xff08;<10&#xff09;&#xff0c;随后给出n本书的信息。每本书在一行中给出书名&#xff0c;即长度不超过30的字…

条码生成器与Zint使用

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

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

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

鸿蒙(HarmonyOS)应用开发——web组件

简述 在开发的工作中&#xff0c;可能存在一个场景&#xff0c;我们有一个问卷调查的h5页面&#xff0c;需要切入到app 中。这个时候&#xff0c;就需要从app 端操作&#xff0c;切换到web端操作。不管是安卓、ios、小程序都提供有web组件。那么harmonyos 中也提供web组件来在…

Kafka中的Topic

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

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

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

GSAP动画库,探究苹果官网页面滚动动画是如何实现的

GSAP动画库&#xff0c;探究苹果官网页面滚动动画是如何实现的 前言 每次浏览苹果官网时都在好奇&#xff0c;当我们向下滚动页面时一个个文字或图片总能缓缓浮现&#xff0c;往上滚动时又能慢慢收起来&#xff0c;这就究竟是如是实现的呢。在查阅一些资料时发现了Scrollmagi…

基于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的串…

Day45| 爬楼梯 (进阶)Leetcode 322. 零钱兑换 Leetcode 279. 完全平方数

爬楼梯 &#xff08;进阶&#xff09; 题目链接 爬楼梯&#xff08;进阶版&#xff09; 本题目属于排列中的背包问题&#xff0c;所以先遍历背包&#xff0c;后遍历物品&#xff0c;剩下的就是完全背包的板子了&#xff0c;下面直接上代码&#xff1a; #include<iostream…

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

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

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

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