「动态规划」买卖股票的最佳时机,如何处理手续费?

2024-06-13 13:28

本文主要是介绍「动态规划」买卖股票的最佳时机,如何处理手续费?,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

给定一个整数数组prices,其中prices[i]表示第i天的股票价格;整数fee代表了交易股票的手续费用。你可以无限次地完成交易,但是你每笔交易都需要付手续费。如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。返回获得利润的最大值。注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要支付一次手续费。

  1. 输入:prices = [1, 3, 2, 8, 4, 9],fee = 2,输出:8,解释:能够达到的最大利润:在此处买入prices[0] = 1,在此处卖出prices[3] = 8,在此处买入prices[4] = 4,在此处卖出prices[5] = 9,总利润:((8 - 1) - 2) + ((9 - 4) - 2) = 8。
  2. 输入:prices = [1,3,7,5,10,3],fee = 3,输出:6。

提示:1 <= prices.length <= 5 * 10^4,1 <= prices[i] < 5 * 10^4,0 <= fee < 5 * 10^4。


我们用动态规划的思想来解决这个问题。

确定状态表示:根据经验和题目要求,我们用dp[i]表示:在第i天结束时,此时的最大利润。

在第i天结束时,如果手中有股票,我们就处于买入状态;如果手中没有股票,我们就处于卖出状态。所以状态表示可以细分为:

  • 用f[i]表示:在第i天结束时,处于买入状态,此时的最大利润。
  • 用g[i]表示:在第i天结束时,处于卖出状态,此时的最大利润。

推导状态转移方程:问题的关键在于如何计算利润。如果我们买入股票,那么利润就要减去股票当天的价格;如果我们卖出股票,那么利润就要加上股票当天的价格。除此之外,还要考虑手续费,根据题目要求,这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要支付一次手续费,我们选择在卖出股票时支付一次手续费,所以在卖出股票时利润要减去手续费。

我们考虑最近的一步,即第i - 1天的状态:

  • 考虑f[i],在第i天结束时处于买入状态,此时的最大利润是以下情况的最大值。
    • 如果在第i - 1天结束时处于买入状态,那么在第i天什么都不做,此时的最大利润就是在第i - 1天结束时处于买入状态的最大利润,即f[i - 1]。
    • 如果在第i - 1天结束时处于卖出状态,那么就要在第i天买入股票,此时的最大利润是在第i - 1天结束时处于卖出状态的最大利润减去股票在第i天的价格,即g[i - 1] - prices[i]。
  • 考虑g[i],在第i天结束时处于卖出状态,此时的最大利润是以下情况的最大值。
    • 如果在第i - 1天结束时处于买入状态,那么就要在第i天卖出股票,此时的最大利润是在第i - 1天结束时处于买入状态的最大利润加上股票在第i天的价格,再减去手续费,即f[i - 1] + prices[i] - fee。
    • 如果在第i - 1天结束时处于卖出状态,那么在第i天什么都不做,此时的最大利润就是在第i - 1天结束时处于卖出状态的最大利润,即g[i - 1]。

综上所述:f[i] = max(f[i - 1], g[i - 1] - prices[i]),g[i] = max(f[i - 1] + prices[i] - fee, g[i - 1])

初始化:根据状态转移方程,我们要初始化f[0]和g[0]的值,防止越界。

  • f[0]表示:在第0天结束时处于买入状态下的最大利润。一开始利润是0,在第0天买入股票,第0天结束时的最大利润就是-prices[0]。
  • g[0]表示:在第0天结束时处于卖出状态下的最大利润。一开始利润是0,在第0天什么都不做,利润仍然是0。

综上所述:f[0] = -prices[0],g[0] = 0

填表顺序:根据状态转移方程,f[i]和g[i]都依赖于f[i - 1]和g[i - 1],所以要沿着i增大的方向同时填f表和g表

返回值:假设总共有n天,那么第i天,i的范围就是[0, n - 1]。要想获得最大利润,在第n - 1天结束时必须处于卖出状态,否则在第n - 1天卖出股票就能获得更多的利润。根据状态表示,我们最终要返回第n - 1天结束时处于卖出状态的最大利润,即g[n - 1]

细节问题:由于f表和g表的下标范围都是[0, n - 1],所以规模都是1 x n

时间复杂度:O(N),空间复杂度:O(N)。

class Solution {
public:int maxProfit(vector<int>& prices, int fee) {int n = prices.size();// 创建dp表vector<int> f(n);auto g = f;// 初始化f[0] = -prices[0];// 填表for (int i = 1; i < n; i++) {f[i] = max(f[i - 1], g[i - 1] - prices[i]);g[i] = max(f[i - 1] + prices[i] - fee, g[i - 1]);}// 返回结果return g[n - 1];}
};

这篇关于「动态规划」买卖股票的最佳时机,如何处理手续费?的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1057425

相关文章

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

python处理带有时区的日期和时间数据

《python处理带有时区的日期和时间数据》这篇文章主要为大家详细介绍了如何在Python中使用pytz库处理时区信息,包括获取当前UTC时间,转换为特定时区等,有需要的小伙伴可以参考一下... 目录时区基本信息python datetime使用timezonepandas处理时区数据知识延展时区基本信息

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删

SpringBoot基于配置实现短信服务策略的动态切换

《SpringBoot基于配置实现短信服务策略的动态切换》这篇文章主要为大家详细介绍了SpringBoot在接入多个短信服务商(如阿里云、腾讯云、华为云)后,如何根据配置或环境切换使用不同的服务商,需... 目录目标功能示例配置(application.yml)配置类绑定短信发送策略接口示例:阿里云 & 腾

Python Transformers库(NLP处理库)案例代码讲解

《PythonTransformers库(NLP处理库)案例代码讲解》本文介绍transformers库的全面讲解,包含基础知识、高级用法、案例代码及学习路径,内容经过组织,适合不同阶段的学习者,对... 目录一、基础知识1. Transformers 库简介2. 安装与环境配置3. 快速上手示例二、核心模

一文详解Java异常处理你都了解哪些知识

《一文详解Java异常处理你都了解哪些知识》:本文主要介绍Java异常处理的相关资料,包括异常的分类、捕获和处理异常的语法、常见的异常类型以及自定义异常的实现,文中通过代码介绍的非常详细,需要的朋... 目录前言一、什么是异常二、异常的分类2.1 受检异常2.2 非受检异常三、异常处理的语法3.1 try-

Python使用getopt处理命令行参数示例解析(最佳实践)

《Python使用getopt处理命令行参数示例解析(最佳实践)》getopt模块是Python标准库中一个简单但强大的命令行参数处理工具,它特别适合那些需要快速实现基本命令行参数解析的场景,或者需要... 目录为什么需要处理命令行参数?getopt模块基础实际应用示例与其他参数处理方式的比较常见问http

Java Response返回值的最佳处理方案

《JavaResponse返回值的最佳处理方案》在开发Web应用程序时,我们经常需要通过HTTP请求从服务器获取响应数据,这些数据可以是JSON、XML、甚至是文件,本篇文章将详细解析Java中处理... 目录摘要概述核心问题:关键技术点:源码解析示例 1:使用HttpURLConnection获取Resp

Java中Switch Case多个条件处理方法举例

《Java中SwitchCase多个条件处理方法举例》Java中switch语句用于根据变量值执行不同代码块,适用于多个条件的处理,:本文主要介绍Java中SwitchCase多个条件处理的相... 目录前言基本语法处理多个条件示例1:合并相同代码的多个case示例2:通过字符串合并多个case进阶用法使用