leetcode 188. Best Time to Buy and Sell Stock IV

目錄

題目描述

第一步,明確并理解dp數組及下標的含義

第二步,分析明確并理解遞推公式

1.求dp[i][j].holding

2.求dp[i][j].sold

第三步,理解dp數組如何初始化

第四步,理解遍歷順序

代碼


題目描述

這道題把第123題推廣為一般情形。第123題限制最多可以完成兩筆交易,這道題改為最多可以完成k筆交易。因此,兩道題沒有本質區別。仍然用第123題的思路來分析。

第一步,明確并理解dp數組及下標的含義

//最多可以完成k筆交易,用j表示交易的序號,j從0開始起算表示第一次交易,j取值范圍是[0,k-1]

//約定好,下文提到的【第j只股票】指的是第j次買入的股票

//dp[i][j].holding表示到第i天結束時,處于持有第j只股票的狀態的最大利潤

//dp[i][j].sold表示到第i天結束時,處于已經賣出第j只股票但是還沒有買入第j+1只股票的狀態下的最大利潤

    struct State{int holding = 0;int sold = 0;};int n = prices.size();//最多可以完成k筆交易,用j表示交易的序號,j從0開始起算表示第一次交易,j取值范圍是[0,k-1]//約定好,下文提到的【第j只股票】指的是第j次買入的股票//dp[i][j].holding表示到第i天結束時,處于持有第j只股票的狀態的最大利潤//dp[i][j].sold表示到第i天結束時,處于已經賣出第j只股票但是還沒有買入第j+1只股票的狀態下的最大利潤vector<vector<State>> dp(n);for(int i =0;i <n;i++)dp[i].resize(k);

第二步,分析明確并理解遞推公式

1.求dp[i][j].holding

//到第i天結束時處于持有第j只股票的狀態,有兩種可能的原因:

//一是前一天(第i-1天)結束時就已經處于持有第j只股票的狀態(對應dp[i-1][j].holding),第i天什么也不做。

//二是第i天買入了第j只股票(需支付prices[i]),第i天能買入第j只股票的前提是前一天(第i-1天)結束時處于已經賣出第j-1只股票但是還沒有買入第j只股票的狀態(對應dp[i-1][j-1].sold)。j如果是0就沒有第j-1只股票,需要特別處理。

int temp = (j > 0) ? (dp[i-1][j-1].sold) : (0);

dp[i][j].holding = max(dp[i-1][j].holding,temp - prices[i]);

2.求dp[i][j].sold

//到第i天結束時處于已經賣出第j只股票但是還沒有買入第j+1只股票的狀態,有兩種可能的原因:

//一是前一天(第i-1天)結束時就已經處于已經賣出第j只股票但是還沒有買入第j+1只股票的狀態(對應dp[i-1][j].sold),第i天什么也不做

//二是第i天賣出了第j只股票(收入prices[i]),第i天能賣出第j只股票的前提是前一天(第i-1天)結束時處于持有第j只股票的狀態(對應狀態dp[i-1][j].holding)

dp[i][j].sold = max(dp[i-1][j].sold,dp[i-1][j].holding + prices[i]);

        for(int i = 1;i < n;i++){for(int j = 0;j < k;j++){//到第i天結束時處于持有第j只股票的狀態,有兩種可能的原因://一是前一天(第i-1天)結束時就已經處于持有第j只股票的狀態(對應dp[i-1][j].holding),第i天什么也不做。//二是第i天買入了第j只股票(需支付prices[i]),第i天能買入第j只股票的前提是前一天(第i-1天)結束時處于已經賣出第j-1只股票但是還沒有買入第j只股票的狀態(對應dp[i-1][j-1].sold)。j如果是0就沒有第j-1只股票,需要特別處理。int temp = (j > 0) ? (dp[i-1][j-1].sold) : (0);dp[i][j].holding = max(dp[i-1][j].holding,temp - prices[i]);//到第i天結束時處于已經賣出第j只股票但是還沒有買入第j+1只股票的狀態,有兩種可能的原因://一是前一天(第i-1天)結束時就已經處于已經賣出第j只股票但是還沒有買入第j+1只股票的狀態(對應dp[i-1][j].sold),第i天什么也不做//二是第i天賣出了第j只股票(收入prices[i]),第i天能賣出第j只股票的前提是前一天(第i-1天)結束時處于持有第j只股票的狀態(對應狀態dp[i-1][j].holding)dp[i][j].sold = max(dp[i-1][j].sold,dp[i-1][j].holding + prices[i]);}}

第三步,理解dp數組如何初始化

for(int j = 0;j <k;j++){

dp[0][j].holding = -prices[0];//到第0天結束時處于持有第j只股票的狀態,可以理解為對第0天的股票買了又賣重復j-1次之后再買入

dp[0][j].sold = 0;//到第0天結束時處于已經賣出第j只股票但是還沒有買入第j+1只股票的狀態,可以理解為對第0天的股票買了又賣重復j次

}

        for(int j = 0;j <k;j++){dp[0][j].holding = -prices[0];//到第0天結束時處于持有第j只股票的狀態,可以理解為對第0天的股票買了又賣重復j-1次之后再買入dp[0][j].sold = 0;//到第0天結束時處于已經賣出第j只股票但是還沒有買入第j+1只股票的狀態,可以理解為對第0天的股票買了又賣重復j次}

第四步,理解遍歷順序

由遞推公式

int temp = (j > 0) ? (dp[i-1][j-1].sold) : (0);

dp[i][j].holding = max(dp[i-1][j].holding,temp - prices[i]);

dp[i][j].sold = max(dp[i-1][j].sold,dp[i-1][j].holding + prices[i]);

可知日期的序號i(或者說股價的序號)應該從小到大遍歷。

可知買入的股票的序號j,也應該從小到大遍歷。

代碼

class Solution {struct State{int holding = 0;int sold = 0;};
public:int maxProfit(int k, vector<int>& prices) {int n = prices.size();//最多可以完成k筆交易,用j表示交易的序號,j從0開始起算表示第一次交易,j取值范圍是[0,k-1]//約定好,下文提到的【第j只股票】指的是第j次買入的股票//dp[i][j].holding表示到第i天結束時,處于持有第j只股票的狀態的最大利潤//dp[i][j].sold表示到第i天結束時,處于已經賣出第j只股票但是還沒有買入第j+1只股票的狀態下的最大利潤vector<vector<State>> dp(n);for(int i =0;i <n;i++)dp[i].resize(k);for(int j = 0;j <k;j++){dp[0][j].holding = -prices[0];//到第0天結束時處于持有第j只股票的狀態,可以理解為對第0天的股票買了又賣重復j-1次之后再買入dp[0][j].sold = 0;//到第0天結束時處于已經賣出第j只股票但是還沒有買入第j+1只股票的狀態,可以理解為對第0天的股票買了又賣重復j次}for(int i = 1;i < n;i++){for(int j = 0;j < k;j++){//到第i天結束時處于持有第j只股票的狀態,有兩種可能的原因://一是前一天(第i-1天)結束時就已經處于持有第j只股票的狀態(對應dp[i-1][j].holding),第i天什么也不做。//二是第i天買入了第j只股票(需支付prices[i]),第i天能買入第j只股票的前提是前一天(第i-1天)結束時處于已經賣出第j-1只股票但是還沒有買入第j只股票的狀態(對應dp[i-1][j-1].sold)。j如果是0就沒有第j-1只股票,需要特別處理。int temp = (j > 0) ? (dp[i-1][j-1].sold) : (0);dp[i][j].holding = max(dp[i-1][j].holding,temp - prices[i]);//到第i天結束時處于已經賣出第j只股票但是還沒有買入第j+1只股票的狀態,有兩種可能的原因://一是前一天(第i-1天)結束時就已經處于已經賣出第j只股票但是還沒有買入第j+1只股票的狀態(對應dp[i-1][j].sold),第i天什么也不做//二是第i天賣出了第j只股票(收入prices[i]),第i天能賣出第j只股票的前提是前一天(第i-1天)結束時處于持有第j只股票的狀態(對應狀態dp[i-1][j].holding)dp[i][j].sold = max(dp[i-1][j].sold,dp[i-1][j].holding + prices[i]);}}int max_profit = 0;for(int j = 0;j < k;j++){if(dp[n-1][j].sold > max_profit)max_profit = dp[n-1][j].sold;}return max_profit;}
};

把本題的代碼中的k改成2,直接可以用作123. Best Time to Buy and Sell Stock III的答案。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/79501.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/79501.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/79501.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【筆記】【C++】【基礎語法】作用域(scope)、持續時間(duration)和鏈接(linkage)

【筆記】【C】【基礎語法】作用域&#xff08;scope&#xff09;、持續時間&#xff08;duration&#xff09;和鏈接&#xff08;linkage&#xff09; 最近正在復習學習C&#xff08;查漏補缺ing&#xff09;。記錄一下學習所得。希望能將所學都整理成一系列的筆記和博客。優先…

Yarn的安裝及環境配置

### Yarn 安裝教程及環境配置步驟 #### 1. 檢查 Node.js 是否已安裝 在安裝 Yarn 前&#xff0c;需確認系統中已經安裝了 Node.js。可以通過以下命令驗證其是否存在并獲取版本號&#xff1a; bash node -v 如果未安裝&#xff0c;則需要先完成 Node.js 的安裝。 --- #### 2…

day2-小白學習JAVA---java第一個程序

java第一個程序 1、新建一個文件&#xff0c;以.java為結尾2、用編輯器打開后寫入代碼&#xff08;本人寫前端&#xff0c;所以用vscode&#xff0c;也可用其他&#xff09;3、編譯文件4、運行文件5、HelloWorld代碼解釋6、文檔注釋 1、新建一個文件&#xff0c;以.java為結尾 …

docker部署springboot(eureka server)項目

打jar包 使用maven&#xff1a; <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>17</source><target>17&…

解讀《人工智能指數報告 2025》:洞察 AI 發展新態勢

美國斯坦福大學 “以人為本人工智能研究院”&#xff08;HAI&#xff09;近日發布的第八版《人工智能指數報告》&#xff08;AI Index Report 2025&#xff09;備受全球矚目。自 2017 年首次發布以來&#xff0c;該報告一直為政策制定者、研究人員、企業高管和公眾提供準確、嚴…

OpenGauss 數據庫介紹

OpenGauss 數據庫介紹 OpenGauss 是華為基于 PostgreSQL 開發的企業級開源關系型數據庫&#xff0c;現已成為開放原子開源基金會的項目。以下是 OpenGauss 的詳細介紹&#xff1a; 一 核心特性 1.1 架構設計亮點 特性說明優勢多核并行NUMA感知架構充分利用現代CPU多核性能行…

使用Trae CN分析項目架構

架構分析后的截圖 A區是打開的項目、B區是源碼區、C區是AI給出當前項目的架構分析結果。 如何用 Trae CN 快速學習 STM32 嵌入式項目架構 在嵌入式開發領域&#xff0c;快速理解現有項目的架構是一項關鍵技能。Trae CN 作為一款強大的分析工具&#xff0c;能幫助開發者高效剖…

MCP協議量子加密實踐:基于QKD的下一代安全通信(2025深度解析版)

一、量子計算威脅的范式轉移與MCP協議改造必要性 1.1 傳統加密體系的崩塌時間表 根據IBM 2025年量子威脅評估報告&#xff0c;當量子計算機達到4000個邏輯量子比特時&#xff08;預計2028年實現&#xff09;&#xff0c;現有非對稱加密體系將在72小時內被完全破解。工業物聯網…

STM32單片機入門學習——第40節: [11-5] 硬件SPI讀寫W25Q64

寫這個文章是用來學習的,記錄一下我的學習過程。希望我能一直堅持下去,我只是一個小白,只是想好好學習,我知道這會很難&#xff0c;但我還是想去做&#xff01; 本文寫于&#xff1a;2025.04.18 STM32開發板學習——第一節&#xff1a; [1-1]課程簡介第40節: [11-5] 硬件SPI讀…

Model Context Protocol (MCP) 開放協議對醫療多模態數據整合的分析路徑【附代碼】

Model Context Protocol (MCP) 作為一種革命性的開放協議,正在重塑醫療領域多模態數據整合的方式。本文將深入分析MCP協議在醫療多模態數據整合中的具體路徑、技術實現、應用場景及未來發展方向,揭示這一協議如何成為連接AI與醫療數據的關鍵橋梁。 MCP協議概述及其在醫療多模…

刀片服務器的散熱構造方式

刀片服務器的散熱構造是其高密度、高性能設計的核心挑戰之一。其散熱系統需在有限空間內高效處理多個刀片模塊產生的集中熱量,同時兼顧能耗、噪音和可靠性。以下從模塊化架構、核心散熱技術、典型方案對比、廠商差異及未來趨勢等方面展開分析: 一、模塊化散熱架構 刀片服務器…

java 排序算法-快速排序

快速排序&#xff08;Quick Sort&#xff09;是一種高效的排序算法&#xff0c;它使用分治法&#xff08;Divide and Conquer&#xff09;策略來把一個序列分為較小和較大的兩個子序列&#xff0c;然后遞歸地排序兩個子序列。 快速排序算法的基本思想&#xff1a; 選擇基準值&…

Linux工具學習之【vim】

&#x1f4d6;vim 基本用法 要想學會 vim 先要學會進入與退出它 &#x1f4c3;進入 vim 首先要保證自己的 Linux 中已經安裝好了 vim &#xff08;云服務器大多數都是出廠就安裝好了&#xff09;&#xff0c;如果沒有安裝&#xff0c;需要在 root 用戶下通過指令 yum instal…

win11系統截圖的幾種方式

在 Windows 11 中&#xff0c;系統內置的截圖功能已全面升級&#xff0c;不僅支持多種截圖模式&#xff0c;還整合了錄屏、OCR 文字識別和 AI 增強編輯等功能。以下是從基礎操作到高階技巧的完整指南&#xff1a; 一、快捷鍵截圖&#xff08;效率首選&#xff09; 1. Win Sh…

寫論文時降AIGC和降重的一些注意事項

‘ 寫一些研究成果&#xff0c;英文不是很好&#xff0c;用有道翻譯過來句子很簡單&#xff0c;句型很單一。那么你會考慮用ai嗎&#xff1f; 如果語句太正式&#xff0c;高級&#xff0c;會被誤判成aigc &#xff0c;慎重選擇ai潤色。 有的話就算沒有用ai生成&#xff0c;但…

Java學習手冊:Java并發編程最佳實踐

在Java并發編程中&#xff0c;遵循最佳實踐可以顯著提高程序的性能、可靠性和可維護性。本文將總結Java并發編程中的關鍵最佳實踐&#xff0c;幫助開發者避免常見陷阱并編寫高效的并發程序。 1. 選擇合適的并發工具 Java提供了豐富的并發工具&#xff0c;選擇合適的工具可以簡…

天梯賽DFS合集

1.DFS特殊輸入&#xff1a;PTA | 程序設計類實驗輔助教學平臺 這題其他還是蠻容易&#xff0c;直接用遞歸即可&#xff0c;問題在于怎么輸入&#xff0c;其實可以在遞歸到底層時輸入即可&#xff0c;也就是邊遞歸邊輸入&#xff0c;另外提一嘴跟這個題沒什么關系的點&#xff…

使用Pydantic優雅處理幾何數據結構 - 前端輸入驗證實踐

使用Pydantic優雅處理幾何數據結構 - 前端輸入驗證實踐 一、應用場景解析 在視頻分析類項目中&#xff0c;前端常需要傳遞幾何坐標數據。例如智能安防系統中&#xff0c;需要接收&#xff1a; 視頻流地址&#xff08;rtsp_video&#xff09;檢測區域坐標點&#xff08;point…

智譜AI大模型免費開放:開啟AI創作新時代

文章摘要&#xff1a;近日&#xff0c;國內領先的人工智能公司智譜AI宣布旗下多款大模型服務免費開放&#xff0c;這一舉措標志著大模型技術正式邁入普惠階段。本文將詳細介紹智譜AI此次開放的GLM-4 等大模型&#xff0c;涵蓋其主要功能、技術特點、使用步驟以及應用場景&#…

JMeter中設置HTTPS請求

在JMeter中設置HTTPS請求&#xff0c;你可以按照以下步驟進行操作&#xff1a; 步驟一&#xff1a;添加線程組 打開JMeter后&#xff0c;右鍵點擊“測試計劃”&#xff0c;選擇“添加” -> “線程&#xff08;用戶&#xff09;” -> “線程組”。線程組用于定義虛擬用戶…