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.mzph.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;” -> “线程组”。线程组用于定义虚拟用户…