leetcode 309. Best Time to Buy and Sell Stock with Cooldown

news2025/7/15 6:02:28

目录

题目描述

第一步,明确并理解dp数组及下标的含义

第二步,分析并理解递推公式

1.求dp[i][0]

2.求dp[i][1]

3.求dp[i][2]

第三步,理解dp数组如何初始化

第四步,理解遍历顺序

代码


题目描述

这道题与第122题的区别就是卖出股票后的一天不能买股票。仍然用动态规划解决。这类题目的关键是要分析每一天有几种状态,用dp数组变量记录这些状态。 

第一步,明确并理解dp数组及下标的含义

//dp[i][0]表示从第0天开始一直到第i天结束时,处于持有股票的状态,此时的最大利润

//dp[i][1]表示从第0天开始一直到第i天结束时,由于第i天卖出股票此时处于不持有股票的状态,此时的最大利润

//dp[i][2]表示从第0天开始一直到第i天结束时,由于第i天之前卖出股票并且第i天没有卖出股票此时处于不持有股票的状态,此时的最大利润

        int n = prices.size();
        //dp[i][0]表示从第0天开始一直到第i天结束时,处于持有股票的状态,此时的最大利润
        //dp[i][1]表示从第0天开始一直到第i天结束时,由于第i天卖出股票此时处于不持有股票的状态,此时的最大利润
        //dp[i][2]表示从第0天开始一直到第i天结束时,由于第i天之前卖出股票并且第i天没有卖出股票此时处于不持有股票的状态,此时的最大利润
        vector<vector<int>> dp(n,vector<int>(3,0));

第二步,分析并理解递推公式

1.求dp[i][0]

//第i天结束时处于持有股票的状态,有两种可能的原因:

//一是前一天(第i-1天)结束时就已经处于持有股票的状态(对应状态dp[i-1][0]),第i天什么也不做。

//二是第i天买入了股票(需支付prices[i]),第i天能买入股票的前提是第i-1天结束时就已经处于不持有股票的状态(并且第i-1天没有卖出股票)(对应状态dp[i-1][2])。

dp[i][0] = max(dp[i-1][0],dp[i-1][2] - prices[i]);

2.求dp[i][1]

//第i天结束时处于不持有股票的状态并且是因为第i天卖出了股票,第i天能卖出股票的前提是第i-1天结束时处于持有股票的状态(对应dp[i-1][0])

dp[i][1] = dp[i-1][0] + prices[i];

3.求dp[i][2]

//第i天结束时处于不持有股票的状态并且第i天没有卖出股票,有两种可能的原因:

//一是前一天(第i-1天)卖出了股票导致第i-1天结束时处于不持有股票的状态(对应状态dp[i-1][1])。

//二是前一天(第i-1天)的之前卖出了股票,而不是前一天的当天卖出了股票,导致第i-1天结束时处于不持有股票的状态(对应状态dp[i-1][2])。

dp[i][2] = max(dp[i-1][1],dp[i-1][2]);

        for(int i = 1;i < n;i++){
            //第i天结束时处于持有股票的状态,有两种可能的原因:
            //一是前一天(第i-1天)结束时就已经处于持有股票的状态(对应状态dp[i-1][0]),第i天什么也不做。
            //二是第i天买入了股票(需支付prices[i]),第i天能买入股票的前提是第i-1天结束时就已经处于不持有股票的状态(并且第i-1天没有卖出股票)(对应状态dp[i-1][2])。
            dp[i][0] = max(dp[i-1][0],dp[i-1][2] - prices[i]);
            //第i天结束时处于不持有股票的状态并且是因为第i天卖出了股票,第i天能卖出股票的前提是第i-1天结束时处于持有股票的状态(对应dp[i-1][0])
            dp[i][1] = dp[i-1][0] + prices[i];
            //第i天结束时处于不持有股票的状态并且第i天没有卖出股票,有两种可能的原因:
            //一是前一天(第i-1天)卖出了股票导致第i-1天结束时处于不持有股票的状态(对应状态dp[i-1][1])。
            //二是前一天(第i-1天)的之前卖出了股票,而不是前一天的当天卖出了股票,导致第i-1天结束时处于不持有股票的状态(对应状态dp[i-1][2])。
            dp[i][2] = max(dp[i-1][1],dp[i-1][2]);
        }

第三步,理解dp数组如何初始化

dp[0][0] = -prices[0];//第0天结束时处于持有股票的状态,那只能是因为第0天买入了股票(需支付prices[0]),利润为负prices[0]

dp[0][1] = 0;//第0天结束时处于不持有股票的状态,并且是因为第0天卖出了股票,可以理解为第0天先买入了股票然后又卖出了,最终利润是0

dp[0][2] = 0;//第0天结束时处于不持有股票的状态,并且第0天没有卖出股票,只能是因为第i天什么也没做,利润保持为初始值0

第四步,理解遍历顺序

第i天的状态依赖于第i-1天的状态,因此i的遍历顺序应该从小到大。

代码

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        //dp[i][0]表示从第0天开始一直到第i天结束时,处于持有股票的状态,此时的最大利润
        //dp[i][1]表示从第0天开始一直到第i天结束时,由于第i天卖出股票此时处于不持有股票的状态,此时的最大利润
        //dp[i][2]表示从第0天开始一直到第i天结束时,由于第i天之前卖出股票并且第i天没有卖出股票此时处于不持有股票的状态,此时的最大利润
        vector<vector<int>> dp(n,vector<int>(3,0));

        dp[0][0] = -prices[0];//第0天结束时处于持有股票的状态,那只能是因为第0天买入了股票(需支付prices[0]),利润为负prices[0]
        dp[0][1] = 0;//第0天结束时处于不持有股票的状态,并且是因为第0天卖出了股票,可以理解为第0天先买入了股票然后又卖出了,最终利润是0
        dp[0][2] = 0;//第0天结束时处于不持有股票的状态,并且第0天没有卖出股票,只能是因为第i天什么也没做,利润保持为初始值0
        for(int i = 1;i < n;i++){
            //第i天结束时处于持有股票的状态,有两种可能的原因:
            //一是前一天(第i-1天)结束时就已经处于持有股票的状态(对应状态dp[i-1][0]),第i天什么也不做。
            //二是第i天买入了股票(需支付prices[i]),第i天能买入股票的前提是第i-1天结束时就已经处于不持有股票的状态(并且第i-1天没有卖出股票)(对应状态dp[i-1][2])。
            dp[i][0] = max(dp[i-1][0],dp[i-1][2] - prices[i]);
            //第i天结束时处于不持有股票的状态并且是因为第i天卖出了股票,第i天能卖出股票的前提是第i-1天结束时处于持有股票的状态(对应dp[i-1][0])
            dp[i][1] = dp[i-1][0] + prices[i];
            //第i天结束时处于不持有股票的状态并且第i天没有卖出股票,有两种可能的原因:
            //一是前一天(第i-1天)卖出了股票导致第i-1天结束时处于不持有股票的状态(对应状态dp[i-1][1])。
            //二是前一天(第i-1天)的之前卖出了股票,而不是前一天的当天卖出了股票,导致第i-1天结束时处于不持有股票的状态(对应状态dp[i-1][2])。
            dp[i][2] = max(dp[i-1][1],dp[i-1][2]);
        }
        return max(dp[n-1][1],dp[n-1][2]);
    }
};

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

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

相关文章

优化自旋锁的实现

在《C11实现一个自旋锁》介绍了分别使用TAS和CAS算法实现自旋锁的方案&#xff0c;以及它们的优缺点。TAS算法虽然实现简单&#xff0c;但是因为每次自旋时都要导致一场内存总线流量风暴&#xff0c;对全局系统影响很大&#xff0c;一般都要对它进行优化&#xff0c;以降低对全…

SS25001-多路复用开关板

1 概述 1.1 简介 多路复用开关板是使用信号继电器实现2线制的多路复用开关板卡&#xff1b;多路复用开关是一种可以将一个输入连接到多个输出或一个输出连接到多个输入的拓扑结构。这种拓扑通常用于扫描&#xff0c;适合将一系列通道自动连接到公共线路的的设备。多路复用开…

【AI News | 20250418】每日AI进展

AI Repos 1、exa-mcp-server AI助手通过Exa获得实时网络信息获取的能力&#xff0c;提供结构化的搜索结果&#xff0c;返回包括标题、URL以及内容片段在内的结构化结果&#xff1b;会把最近的搜索结果缓存为资源&#xff0c;下次再搜索相同的内容时可以直接使用缓存&#xff1…

Dify LLM大模型参数(一)

深入了解大语言模型&#xff08;LLM&#xff09;的参数设置 模型的参数对模型的输出效果有着至关重要的影响。不同的模型会拥有不同的参数&#xff0c;而这些参数的设置将直接影响模型的生成结果。以下是 DeepSeek 模型参数的详细介绍&#xff1a; 温度&#xff08;Tempera…

展示数据可视化的魅力,如何通过图表、动画等形式让数据说话

在当今信息爆炸的时代&#xff0c;数据的量级和复杂性不断增加。如何从海量数据中提取有价值的信息&#xff0c;并将其有效地传达给用户&#xff0c;成为了一个重要的课题。数据可视化作为一种将复杂数据转化为直观图形、图表和动画的技术&#xff0c;能够帮助用户快速理解数据…

时序预测 | Matlab实现基于VMD-WOA-ELM和VMD-ELM变分模态分解结合鲸鱼算法优化极限学习机时间序列预测

时序预测 | Matlab实现基于VMD-WOA-ELM和VMD-ELM变分模态分解结合鲸鱼算法优化极限学习机时间序列预测 目录 时序预测 | Matlab实现基于VMD-WOA-ELM和VMD-ELM变分模态分解结合鲸鱼算法优化极限学习机时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab…

基于EasyX库开发的球球大作战游戏

目录 球球大作战 一、开发环境 二、流程图预览 三、代码逻辑 1、初始化时间 2、设置开始界面大小 3、设置开始界面 4、让玩家选择速度 5、设置玩家小球、人机小球、食物的属性 6、一次性把图绘制到界面里 7、进入死循环 8、移动玩家小球 9、移动人机 10、食物刷新…

《系统分析师-第三阶段—总结(一)》

背景 采用三遍读书法进行阅读&#xff0c;此阶段是第三遍。 过程 第一章 第二章 总结 在这个过程中&#xff0c;对导图的规范越来越清楚&#xff0c;开始结构化&#xff0c;找关系&#xff0c;找联系。

AI——K近邻算法

文章目录 一、什么是K近邻算法二、KNN算法流程总结三、Scikit-learn工具1、安装2、导入3、简单使用 三、距离度量1、欧式距离2、曼哈顿距离3、切比雪夫距离4、闵可夫斯基距离5、K值的选择6、KD树 一、什么是K近邻算法 如果一个样本在特征空间中的k个最相似&#xff08;即特征空…

用 NLP + Streamlit,把问卷变成能说话的反馈

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…

TCP/IP和UDP协议的发展历程

TCP/IP和UDP协议的发展历程 引言 互联网的发展史是人类技术创新的辉煌篇章&#xff0c;而在这一发展过程中&#xff0c;通信协议发挥了奠基性的作用。TCP/IP&#xff08;传输控制协议/互联网协议&#xff09;和UDP&#xff08;用户数据报协议&#xff09;作为互联网通信的基础…

Function Calling的时序图(含示例)

&#x1f9cd; 用户&#xff1a; 发起请求&#xff0c;输入 prompt&#xff08;比如&#xff1a;“请告诉我北京的天气”&#xff09;。 &#x1f7ea; 应用&#xff1a; 将用户输入的 prompt 和函数定义&#xff08;包括函数名、参数结构等&#xff09;一起发给 OpenAI。 …

若依框架修改左侧菜单栏默认选中颜色

1.variables.sacc中修改为想要的颜色 2.给目标设置使用的颜色

搜广推校招面经七十八

字节推荐算法 一、实习项目&#xff1a;多任务模型中的每个任务都是做什么&#xff1f;怎么确定每个loss的权重 这个根据实际情况来吧。如果实习时候用了moe&#xff0c;就可能被问到。 loss权重的话&#xff0c;直接根据任务的重要性吧。。。 二、特征重要性怎么判断的&…

广搜bfs-P1443 马的遍历

P1443 马的遍历 题目来源-洛谷 题意 要求马到达棋盘上任意一个点最少要走几步 思路 国际棋盘规则是马的走法是-日字形&#xff0c;也称走马日&#xff0c;即x,y一个是走两步&#xff0c;一个是一步 要求最小步数&#xff0c;所以考虑第一次遍历到的点即为最小步数&#xff…

强化学习算法系列(六):应用最广泛的算法——PPO算法

强化学习算法 &#xff08;一&#xff09;动态规划方法——策略迭代算法(PI)和值迭代算法(VI) &#xff08;二&#xff09;Model-Free类方法——蒙特卡洛算法(MC)和时序差分算法(TD) &#xff08;三&#xff09;基于动作值的算法——Sarsa算法与Q-Learning算法 &#xff08;四…

AI Agents系列之AI代理架构体系

1. 引言 智能体架构是定义智能体组件如何组织和交互的蓝图,使智能体能够感知其环境、推理并采取行动。本质上,它就像是智能体的数字大脑——集成了“眼睛”(传感器)、“大脑”(决策逻辑)和“手”(执行器),用于处理信息并采取行动。 选择正确的架构对于构建有效的智能…

2025海外代理IP测评:Bright Data,ipfoxy,smartproxy,ipipgo,kookeey,ipidea哪个值得推荐?

近年来&#xff0c;随着全球化和跨境业务需求的不断扩大“海外代理IP”逐渐成为企业和个人在多样化场景中的重要工具。无论是进行数据采集、广告验证、社交媒体管理&#xff0c;还是跨境电商平台运营&#xff0c;选择合适的代理IP服务商都显得尤为重要。然而&#xff0c;市场上…

Android守护进程——Vold (Volume Daemon)

简介 介绍&#xff1a;Vold 是用来管理 android 系统的存储设备&#xff0c;如U盘、SD卡、磁盘等移动设备的热插拔、挂载、卸载、格式化 框架结构&#xff1a;Vold 在系统中以守护进程存在&#xff0c;是一个单独的进程。处于Kernel和Framework之间&#xff0c;是两个层级连接…

vue3+vite 实现.env全局配置

首先创建.env文件 VUE_APP_BASE_APIhttp://127.0.0.1/dev-api 然后引入依赖&#xff1a; pnpm install dotenv --save-dev 引入完成后&#xff0c;在vite.config.js配置文件内加入以下内容&#xff1a; const env dotenv.config({ path: ./.env }).parsed define: { // 将…