多状态动态规划之买卖股票的最佳时机含手续费

简介: 多状态动态规划之买卖股票的最佳时机含手续费

1. 题目分析



题目链接选自力扣 : 买卖股票的最佳时机含手续费

2bc2c6d16b2358e9e656c39feea50f1b.png

根据示例 1 进行分析 :

4f0cb65ebadc98c9cc0d91d3e269a2b3.png


示例 2 :

image.png


总的来说, 和我们之前的 " 最佳买卖股票 " 有点类似. 遵循以下规则

  1. 当天手上没有股票可以选择不买入
  2. 当天手上有股票可以选择不卖出
  3. 当天手上没有股票可以选择买入
  1. 手上有股票必须卖出才可以进行买入操作
  2. 根据用户的不同操作, 尽可能的获得更多的利润. ( 低价收入高价卖出 )


PS : 这里的买入和卖出只得是一笔交易. 也就是说, 当你买入后再卖出时一瞬间会扣取手续费. 买入时并不会扣除, 只有卖掉股票时才会扣 !


2. 状态表示



以 i 为结尾, 表示从第一天到结束时, 所获得的最大利润

不难发现, 当第 i 天结束的时候, 又有两种情况.


  1. 第 i 天结束时为买入状态

这种情况, 我们以 f[i] 表示, 即从第一天开始到第 i 天结束时, 第 i 天处于买入状态时所获得的最大利润.


  1. 第 i 天结束时为卖出状态

这种情况, 我们以 g[i] 表示, 即从第一天开始到第 i 天结束时, 第 i 天处于卖出转态时所获得的最大利润.


3. 状态转移方程



根据上面两个状态表示可以看出, 这是一个多状态的问题. 因此我们对这两个状态分别进行状态转移方程的分析.

a379b71ba0bbcafac470cc768a856057.png

  1. 第 i 天结束时为买入状态

那么, 如何才能在第 i 天结束时为买入状态呢 ? 那我们就需要观察 i - 1 前一天的状态了.


  1. i - 1 为买入状态, 第 i 天不进行操作, 第 i 天结束后依然为买入状态

这种情况下, 其对应的花费为从第一天到第 i - 1 天结束为买入状态时所获得的最大利润, 对应到状态表示中则为 f[i-1], 第 i 天由于不操作, 最终利润为 f[i-1]


  1. i - 1 为卖出状态, 第 i 天进行买入操作, 第 i 天结束后则为买入状态.


这种情况下, 其对应的花费为从第一天到第 i - 1 天结束为卖出状态时所获得的最大利润, 对应到状态表示中则为 g[i-1], 并且在第 i 天买入, 最终利润为 g[i-1]-prices[i]


最终第 i 天结束时为买入状态的状态表示为 f[i] = Math.max(g[i-1]-prices[i], f[i-1]), 为两种情况下的最大利润.


  1. 第 i 天结束时为卖出状态
  1. i - 1 天为买入状态, 第 i 天进行卖出操作, 第 i 天结束后则为卖出状态


这种情况下, 其对应的花费为从第一天到第 i - 1 天结束为卖出状态时所获得的最大利润, 对应到状态表示中则为 f[i-1], 由于在第 i 天进行卖出, 最终利润为 f[i-1] + prices[i]-fee


  1. i - 1 天为卖出状态, 第 i 天不进行操作, 则第 i 天接受后依然为卖出状态 ( 可交易 )


这种情况下, 其对应的花费为从第一天到第 i - 1 天结束为卖出状态时所获得的最大利润, 对应到状态表示中则为 g[i-1], 由于第 i 天不进行操作. 因此最终利润为 g[i-1]


最终第 i 天结束时为卖出状态的状态表示为 g[i] = Math.max(f[i-1] + prices[i]-fee, g[i-1]), 为两种情况下的最大利润


4. 初始化



根据状态转移方程, f[0] 和 g[0] 在填表时会发生越界错误, 因此需要单独进行初始化.

如果第 1 天结束时为买入状态, 之后整个股票交易就结束了, 此时还没有卖出股票, 手上的利润为 -prices[0] ( 负数 )


如果第 1 天结束时为卖出状态, 之后整个股票交易就结束了, 此时为 0 , 等同于这一天买入后又卖出去了. ( 这句话需要各位好好体会一下 )


5. 填表顺序



根据状态转移方程, 想要知道 i 位置结束时获得的最大利润, 要先知道前一天的最大利润. 因此填表顺序为从左往右


6. 返回值



返回第 n 天结束时, 所获得的最大利润. 对应到我们的状态表示中则为两种不同状态下第 n 天的最大值. 即 Math.max(f[n-1], g[n-1]) ( 注意 n 为数组长度, 和下标的对应关系 )


7. 代码演示



class Solution {
    public int maxProfit(int[] prices, int fee) {
        // 1. 创建 dp 表
        int n = prices.length;
        int[] f = new int[n]; // i 位置结束时为买入状态所获得的最大利润
        int[] g = new int[n]; // i 位置结束时为卖出状态所获得的最大利润
        // 2. 初始化
        f[0] = -prices[0];
        // 3. 填写 dp 表
        for(int i = 1; i < n; i++) {
             f[i] = Math.max(g[i - 1]-prices[i], f[i - 1]);
             g[i] = Math.max(f[i - 1] + prices[i]-fee, g[i - 1]);
        }
        // 4. 确认返回值
        return Math.max(f[n - 1], g[n - 1]);
    }
}


相关文章
|
安全 物联网 Linux
带你读《物联网渗透测试》之三:固件分析与漏洞利用
本书介绍物联网渗透测试的原理和实用技术。主要内容包括IOT威胁建模、固件分析及漏洞利用、嵌入式web应用漏洞、IOT移动应用漏洞、IOT设备攻击、无线电入侵、固件安全和移动安全最佳实践、硬件保护以及IOT高级漏洞的利用与安全自动化。
|
12月前
|
人工智能 运维 Cloud Native
开源聚合平台 Websoft9:开源创新已成为中小企业数字化转型、数据驱动企业的基础
Websoft9作为全球领先的开源聚合平台,助力中小企业通过开源软件实现数字化转型。其AI驱动的开源操作系统破解技术鸿沟,提供智能选型、云原生部署和智能运维三大引擎,降低企业成本并提升效率。某跨境电商案例显示,Websoft9帮助其实现建站、数据分析、智能客服及ERP升级等全面优化。平台将企业IT投入降至$99/月起,应用上线周期缩短至72小时,系统可用性达99.95% SLA保障。
300 2
开源聚合平台 Websoft9:开源创新已成为中小企业数字化转型、数据驱动企业的基础
|
人工智能 架构师 Java
最高裁95%,只留5% 用AI的,某上市公司全面ai化。你的岗位,AI入侵指数是 多少?多久消失?
本文探讨了AI对不同岗位的冲击及未来趋势,特别提到上美股份大规模裁员以保留能使用AI的员工。文中分析了Java开发、大数据开发、架构师、产品经理等岗位的AI入侵指数,指出高风险和低风险岗位,并建议进入AI入侵指数低的领域如Java+AI+大数据架构师。此外,文章还介绍了尼恩团队的大模型学习资源和面试指导服务,帮助从业者提升技能,应对AI时代的挑战。
|
人工智能 安全
openAI的Red Team
openAI的Red Team
713 3
|
监控 BI 数据安全/隐私保护
ERP系统中的成本核算与管理会计解析
【7月更文挑战第25天】 ERP系统中的成本核算与管理会计解析
1120 4
|
存储 算法 程序员
操作系统(11)----内存管理5
操作系统(11)----内存管理
689 1
操作系统(11)----内存管理5
|
API 数据处理 数据库
掌握 Kotlin Flow 的艺术:让无限数据流处理变得优雅且高效 —— 实战教程揭秘如何在数据洪流中保持代码的健壮与灵活
Kotlin Flow 是一个强大的协程 API,专为处理异步数据流设计。它适合处理网络请求数据、监听数据库变化等场景。本文通过示例代码展示如何使用 Kotlin Flow 管理无限流,如实时数据流。首先定义了一个生成无限整数的流 `infiniteNumbers()`,然后结合多种操作符(如 `buffer`、`onEach`、`scan`、`filter`、`takeWhile` 和 `collectLatest`),实现对无限流的优雅处理,例如计算随机数的平均值并在超过阈值时停止接收新数据。这展示了 Flow 在资源管理和逻辑清晰性方面的优势。
336 0
|
开发框架 分布式计算 API