【每日一題】出租車的最大盈利

文章目錄

  • 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(i?1)

在情況二中,我們可以枚舉搭載哪位乘客,取其中最賺錢的方案,有轉移關系式:

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)+i?start+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(i?1),max(dfs(start)+i?start+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[i?1],max(f[start]+i?end+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.pswp.cn/news/206715.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/206715.shtml
英文地址,請注明出處:http://en.pswp.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;從而造成服務不可用的情況。為了解決這個…