代码随想录算法训练营第55天|动态规划part12|309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费、总结

news2024/12/30 3:37:47

代码随想录算法训练营第55天|动态规划part12|309.最佳买卖股票时机含冷冻期、714.买卖股票的最佳时机含手续费、总结

309.最佳买卖股票时机含冷冻期

309.最佳买卖股票时机含冷冻期

思路:

区别在第i天持有股票的当天买入的情况,买入因为有冷静期1天,如果之前有过交易,手里的利润应该是dp[i-1-1][1]也就是前两天不持有股票情况下的最大利润,然后再当天买入,就是dp[i-1-1][1]-price[i]

其他的地方都一样。

代码:

python

class Solution(object):
    def maxProfit(self, prices):
        """
        :type prices: List[int]
        :rtype: int
        """
        '''
        状态有几种:
        第i天持有股票:1. 继续持有 2. 买入 
        dp[i][0] = max(dp[i-1][0], dp[i-1-1][1]-price[i])
        第i天不持有股票:1. 当天卖出,后一天不允许交易 2. 前一天卖出今天是冷静期
        dp[i][1] = max(dp[i-1][0] + price[i], dp[i-1][1])
        
        '''
        dp = [[0, 0] for _ in range(len(prices))]

        dp[0][0] = 0 - prices[0]
        dp[0][1] = 0

        for i in range(1, len(prices)):
            if i > 1: 
                dp[i][0] = max(dp[i-1][0], dp[i-1-1][1]-prices[i])
            else:
                dp[i][0] = max(dp[i-1][0], dp[i-1][1]-prices[i])

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

        return dp[len(prices)-1][1]

代码随想录

这道题的重点在于全面的分析出有几种状态!!!

思路:

相对于动态规划:122.买卖股票的最佳时机II (opens new window),本题加上了一个冷冻期

动规五部曲,分析如下:

  1. 确定dp数组以及下标的含义

dp[i][j],第i天状态为j,所剩的最多现金为dp[i][j]。

其实本题很多同学搞的比较懵,是因为出现冷冻期之后,状态其实是比较复杂度,例如今天买入股票、今天卖出股票、今天是冷冻期,都是不能操作股票的。

具体可以区分出如下四个状态:

  • 状态一:持有股票状态(当天持有, 和 一直持有
  • 不持有股票状态,这里就有两种卖出股票状态
    • 状态二:保持卖出股票的状态(两天前就卖出了股票,度过一天冷冻期。或者是前一天就是卖出股票状态,一直没操作)
    • 状态三:今天卖出股票
  • 状态四:今天为冷冻期状态,但冷冻期状态不可持续,只有一天!

j的状态为:

0:状态一
1:状态二
2:状态三
3:状态四

很多题解为什么讲的比较模糊,是因为把这四个状态合并成三个状态了,其实就是把状态二和状态四合并在一起了。

从代码上来看确实可以合并,但从逻辑上分析合并之后就很难理解了,所以我下面的讲解是按照这四个状态来的,把每一个状态分析清楚。

如果大家按照代码随想录顺序来刷的话,会发现 买卖股票最佳时机 1,2,3,4 的题目讲解中

动态规划:121.买卖股票的最佳时机(opens new window)
动态规划:122.买卖股票的最佳时机II(opens new window)
动态规划:123.买卖股票的最佳时机III(opens new window)
动态规划:188.买卖股票的最佳时机IV(opens new window)

「今天卖出股票」我是没有单独列出一个状态的归类为「不持有股票的状态」,而本题为什么要单独列出「今天卖出股票」 一个状态呢?

因为本题我们有冷冻期,而冷冻期的前一天,只能是 「今天卖出股票」状态,如果是 「不持有股票状态」那么就很模糊,因为不一定是 卖出股票的操作。

注意这里的每一个状态,例如状态一,是持有股票股票状态并不是说今天一定就买入股票,而是说保持买入股票的状态即:可能是前几天买入的,之后一直没操作,所以保持买入股票的状态。

  1. 确定递推公式

达到买入股票状态(状态一)即:dp[i][0],有两个具体操作:

  • 操作一:前一天就是持有股票状态(状态一),dp[i][0] = dp[i - 1][0]
  • 操作二:今天买入了,有两种情况
    • 前一天是冷冻期(状态四),dp[i - 1][3] - prices[i]
    • 前一天是保持卖出股票的状态(状态二),dp[i - 1][1] - prices[i]

那么dp[i][0] = max(dp[i - 1][0], dp[i - 1][3] - prices[i], dp[i - 1][1] - prices[i]);

达到保持卖出股票状态(状态二)即:dp[i][1],有两个具体操作:

  • 操作一:前一天就是状态二
  • 操作二:前一天是冷冻期(状态四)

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

达到今天就卖出股票状态(状态三),即:dp[i][2] ,只有一个操作:

昨天一定是持有股票状态(状态一),今天卖出

即:dp[i][2] = dp[i - 1][0] + prices[i];

达到冷冻期状态(状态四),即:dp[i][3],只有一个操作:

昨天卖出了股票(状态三)

dp[i][3] = dp[i - 1][2];

综上分析,递推代码如下:

dp[i][0] = max(dp[i - 1][0], max(dp[i - 1][3], dp[i - 1][1]) - prices[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]);
dp[i][2] = dp[i - 1][0] + prices[i];
dp[i][3] = dp[i - 1][2];
  1. dp数组如何初始化

如果是持有股票状态(状态一)那么:dp[0][0] = -prices[0],一定是当天买入股票。

保持卖出股票状态(状态二),这里其实从 「状态二」的定义来说 ,很难明确应该初始多少,这种情况我们就看递推公式需要我们给他初始成什么数值。

如果i为1,第1天买入股票,那么递归公式中需要计算 dp[i - 1][1] - prices[i] ,即 dp[0][1] - prices[1],那么大家感受一下 dp[0][1] (即第0天的状态二)应该初始成多少,只能初始为0。想一想如果初始为其他数值,是我们第1天买入股票后 手里还剩的现金数量是不是就不对了。

今天卖出了股票(状态三),同上分析,dp[0][2]初始化为0,dp[0][3]也初始为0。

  1. 确定遍历顺序

从递归公式上可以看出,dp[i] 依赖于 dp[i-1],所以是从前向后遍历。

  1. 举例推导dp数组

以 [1,2,3,0,2] 为例,dp数组如下:

在这里插入图片描述
最后结果是取 状态二,状态三,和状态四的最大值,不少同学会把状态四忘了,状态四是冷冻期,最后一天如果是冷冻期也可能是最大值。

代码:

python

from typing import List

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        n = len(prices)
        if n == 0:
            return 0
        dp = [[0] * 4 for _ in range(n)]  # 创建动态规划数组,4个状态分别表示持有股票、不持有股票且处于冷冻期、不持有股票且不处于冷冻期、不持有股票且当天卖出后处于冷冻期
        dp[0][0] = -prices[0]  # 初始状态:第一天持有股票的最大利润为买入股票的价格
        for i in range(1, n):
            dp[i][0] = max(dp[i-1][0], max(dp[i-1][3], dp[i-1][1]) - prices[i])  # 当前持有股票的最大利润等于前一天持有股票的最大利润或者前一天不持有股票且不处于冷冻期的最大利润减去当前股票的价格
            dp[i][1] = max(dp[i-1][1], dp[i-1][3])  # 当前不持有股票且处于冷冻期的最大利润等于前一天持有股票的最大利润加上当前股票的价格
            dp[i][2] = dp[i-1][0] + prices[i]  # 当前不持有股票且不处于冷冻期的最大利润等于前一天不持有股票的最大利润或者前一天处于冷冻期的最大利润
            dp[i][3] = dp[i-1][2]  # 当前不持有股票且当天卖出后处于冷冻期的最大利润等于前一天不持有股票且不处于冷冻期的最大利润
        return max(dp[n-1][3], dp[n-1][1], dp[n-1][2])  # 返回最后一天不持有股票的最大利润

714. 买卖股票的最佳时机含手续费

714. 买卖股票的最佳时机含手续费

思路:

相对122.买卖股票的最佳时机II ,本题只需要在计算卖出操作的时候减去手续费就可以了,代码几乎是一样的,可以尝试自己做一做。

代码:

python

class Solution(object):
    def maxProfit(self, prices, fee):
        """
        :type prices: List[int]
        :type fee: int
        :rtype: int
        """
        dp = [[0, 0] for _ in range(len(prices))]

        dp[0][0] = 0 - prices[0]
        dp[0][1] = 0

        for i in range(1, len(prices)):
            dp[i][0] = max(dp[i-1][0], dp[i-1][1]-prices[i])
            dp[i][1] = max(dp[i-1][1], prices[i] + dp[i-1][0] - fee)

        return dp[len(prices)-1][1]

总结

总结

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

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

相关文章

【Kubernetes】神乎其技的K8s到底是什么,为什么被越来越多人使用

🚀欢迎来到本文🚀 🍉个人简介:陈童学哦,目前学习C/C、算法、Python、Java等方向,一个正在慢慢前行的普通人。 🏀系列专栏:陈童学的日记 💡其他专栏:CSTL&…

户外骨传导耳机推荐,盘点最适合户外佩戴的五款耳机

现在天气越来越暖和了,很多人选择外出徒步、越野或者骑行,在这些活动中往往都会搭配一个骨传导耳机,来让运动过程变得更加有趣。在选购骨传导耳机时,人们通常会考虑音质、舒适性、价格等因素,为了让大家选到更适合自己…

Kafka API与SpringBoot调用

文章目录 首先需要命令行创建一个名为cities的主题,并且创建该主题的订阅者。 1、使用Kafka原生API1.1、创建spring工程1.2、创建发布者1.3、对生产者的优化1.4、批量发送消息1.5、创建消费者组1.6 消费者同步手动提交1.7、消费者异步手动提交1.8、消费者同异步手动…

yolov5目标检测多线程Qt界面

上一篇文章&#xff1a;yolov5目标检测多线程C部署 V1 基本功能实现 mainwindow.h #pragma once#include <iostream>#include <QMainWindow> #include <QFileDialog> #include <QThread>#include <opencv2/opencv.hpp>#include "yolov5.…

phpspreadsheet excel导入导出

单个sheet页Excel2003版最大行数是65536行。Excel2007开始的版本最大行数是1048576行。Excel2003的最大列数是256列&#xff0c;2007以上版本是16384列。 xlswriter xlswriter - PHP 高性能 Excel 扩展&#xff0c;功能类似phpspreadsheet。它能够处理非常大的文件&#xff0…

056B R包ENMeval教程-基于R包ENMeval对MaxEnt模型优化调参和结果评价制图(更新)

056B-1 资料下载 056B-2 R包ENMeval在MaxEnt模型优化调参中的经典案例解读 056B-3 R软件和R包ENMeval工具包安装 056B-4 R软件和R包ENMeval安装报错解决办法 056B-5 环境数据格式要求和处理流程 056B-6 分布数据格式要求和处理流程 056B-7 基于R包ENMeval对MaxEnt模型优化…

12.pod生命周期和存储卷

文章目录 pod生命周期pod启动阶段故障排除步骤&#xff1a; 存储卷emptyDir存储卷 hostPath存储卷nfs共享存储卷总结&#xff1a; pod生命周期 pod启动阶段 一般来说&#xff0c;pod 这个过程包含以下几个步骤&#xff1a; 调度到某台 node 上。kubernetes 根据一定的优先级算…

【C#】静默安装、SQL SERVER静默安装等

可以通过cmd命令行来执行&#xff0c;也可以通过代码来执行&#xff0c;一般都需要管理员权限运行 代码 /// <summary>/// 静默安装/// </summary>/// <param name"fileName">安装文件路径</param>/// <param name"arguments"…

Dubbo 2.7.0 CompletableFuture 异步

了解Java中Future演进历史的同学应该知道&#xff0c;Dubbo 2.6.x及之前版本中使用的Future是在java 5中引入的&#xff0c;所以存在以上一些功能设计上的问题&#xff0c;而在java 8中引入的CompletableFuture进一步丰富了Future接口&#xff0c;很好的解决了这些问题。 Dubb…

小内存嵌入式设备软件的差分升级设计(学习)

摘要 提出一种改进HDiffPatch算法并在复旦微单片机上实现小内存差分升级的方案&#xff0c;即使用单片机内的Flash空间替代算法占用的RAM空间&#xff0c;从而减少算法对单片机RAM空间的需求&#xff0c;以满足小内存微处理器的差分升级&#xff0c;同时对算法内存分配释放函数…

HashMap源码探究之底“库”看穿

前言&#xff1a; 本次的源码探究会以jdk1.7和jdk1.8对比进行探究二者在HashMap实现上有的差异性&#xff0c;除此之外&#xff0c;还会简单介绍HashMap的hash算法的设计细节、jdk1.8中HashMap添加功能的整个流程、什么情况下会树化等源码设计知识。 一、HashMap介绍 HashMap…

SpringBoot3数据库集成

标签&#xff1a;Jdbc.Druid.Mybatis.Plus&#xff1b; 一、简介 项目工程中&#xff0c;集成数据库实现对数据的增晒改查管理&#xff0c;是最基础的能力&#xff0c;而对于这个功能的实现&#xff0c;其组件选型也非常丰富&#xff1b; 通过如下几个组件来实现数据库的整合…

Spring Cloud 智慧工地源码(PC端+移动端)项目平台、监管平台、大数据平台

智慧工地源码 智慧工地云平台源码 智慧建筑源码 “智慧工地”是利用物联网、人工智能、云计算、大数据、移动互联网等新一代信息技术&#xff0c;彻底改变传统建筑施工现场参建各方现场管理的交互方式、工作方式和管理模式&#xff0c;实现对人、机、料、法、环的全方位实时监…

uniapp开发公众号,微信开发者工具进行本地调试

每次修改完内容都需要发行之后&#xff0c;再查看效果&#xff0c;很麻烦 &#xff01;&#xff01;&#xff01; 下述方法&#xff0c;可以一边在uniapp中修改内容&#xff0c;一边在微信开发者工具进行本地调试 修改hosts文件 在最后边添加如下内容 修改前端开发服务端口 …

Android 第一行代码学习 -- 聊天界面小练习

前言&#xff1a;最近在学习安卓&#xff0c;阅读入门书籍第一行代码&#xff0c;以后更新的知识可能大部分都会和安卓有关。 实现聊天界面 1.编写主界面 个人觉得界面编写刚开始学可能看着很乱&#xff0c;但是其中最重要的是层次&#xff0c;看懂了其中的层次&#xff0c;就…

论element-ui表格的合并行和列(巨细节)

论element-ui表格的合并行和列 0、前言 ​ 作为一个后端来写前端属实是痛苦、讲真的、刚开始我是真不想用饿了么的这个合并行和列、因为太语焉不详了、看着头疼、后来发现好像我没得选、只好硬着头皮上了。 1、element - ui 的合并行和列代码 效果图&#xff1a; 代码&…

SpringSecurity环境搭建

AOP思想&#xff1a;面向切面编程 导入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation&quo…

【算法题】螺旋矩阵II (求解n阶Z形矩阵)

一、问题的提出 n阶Z形矩阵的特点是按照之(Z)字形的方式排列元素。n阶Z形矩阵是指矩阵的大小为nn&#xff0c;其中n为正整数。 题目描述 一个 n 行 n 列的螺旋(Z形)矩阵如图1所示&#xff0c;观察并找出填数规律。 图1 7行7列和8行8列的螺旋(Z形)矩阵 现在给出矩阵大小 n&…

异步电机模型预测转矩控制MPTC关键技术(1、一拍延迟补偿)

导读&#xff1a;本期文章主要介绍异步电机模型预测转矩控制MPTC中的一拍延迟补偿的内容。先进性一拍延迟补偿原理的介绍&#xff0c;之后进行仿真验证补偿的有效性。 如果需要文章中的仿真模型&#xff0c;关注微信公众号&#xff1a;浅谈电机控制&#xff0c;留言获取。 一…

Vue输入框或者选择框无效,或者有延迟

问题剖析 使用Vue这种成熟好用的框架&#xff0c;一般出现奇奇怪怪的问题都是因为操作不当导致的&#xff0c;例如没有合理调用组件、组件位置不正确、没有合理定义组件或者变量、样式使用不当等等... 解决方案 如果你也出现了输入框输入东西&#xff0c;但是没有效果…