动态规划-买卖股票的最佳时机Ⅳ

server/2024/11/14 15:19:12/

题目描述

给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说,你最多可以买 k 次,卖 k 次。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 :

输入:k = 2, prices = [2,4,1]
输出:2
解释:在第 1 天 (股票价格 = 2) 的时候买入,在第 2 天 (股票价格 = 4) 的时候卖出,这笔交易所能获得利润 = 4-2 = 2 。

 解题思路

数组定义

在这个解决方案中,我们使用了两个二维数组fg来跟踪每一天和每一次交易后的最大利润。

  • f[i][j]:表示第i天结束后,进行了j次交易(注意这里的j次交易包括买入和卖出),并且当前手中持有股票时的最大利润。
  • g[i][j]:表示第i天结束后,进行了j次交易,并且当前手中没有股票时的最大利润。

初始化

  • f[0][0]:第一天没有交易,如果持有股票,则必须是在第一天买入的,所以利润是-prices[0]
  • g[0][0]:第一天没有交易,没有股票,利润为0。
  • 对于j > 0的情况,第一天不可能完成多于一次的交易,所以f[0][j]g[0][j]都初始化为一个非常小的数(例如INT_MIN-0x3f3f3f),表示这些状态是无效的。

状态转移

对于每一天i和每一次交易数j

  • 更新f[i][j]:你可以选择在第i天继续持有股票(即继承前一天的f[i-1][j]),或者你可以选择在第i天买入股票(但前提是之前已经完成了j-1次交易,即从前一天的g[i-1][j-1]状态转移而来,并减去今天的股票价格)。
  • 更新g[i][j]:你可以选择在第i天不进行操作(即继承前一天的g[i-1][j]),或者你可以选择在第i天卖出股票(但前提是之前已经买入了股票,即从前一天的f[i-1][j]状态转移而来,并加上今天的股票价格)。

状态转移方程

1. f[i][j] 的状态转移方程

f[i][j] 表示第 i 天结束后,完成了 j 次交易(包括买入和卖出),并且当前手中持有股票时的最大利润。

  • 如果我们在第 i 天选择不进行操作(即继续持有前一天买入的股票),那么 f[i][j] 的值应该等于前一天的相同状态 f[i-1][j]
  • 如果我们在第 i 天选择买入股票(这必须是在之前已经完成了 j 次交易之后),那么我们需要从前一天的“不持有股票但已完成 j 次交易”的状态 g[i-1][j] 转移而来,并减去今天的股票价格 prices[i]

因此,f[i][j] 的状态转移方程为:

f[ i ][ j ] = max(f[ i − 1 ][ j ],g[ i − 1 ][ j ] − prices[ i ])

2. g[i][j] 的状态转移方程

g[i][j] 表示第 i 天结束后,完成了 j 次交易,并且当前手中没有股票时的最大利润。

  • 如果我们在第 i 天选择不进行操作(即保持前一天的状态),那么 g[i][j] 的值应该等于前一天的相同状态 g[i-1][j]
  • 如果我们在第 i 天选择卖出股票(卖出股票后j++,在第 i - 1 天时实际完成了 j - 1 次交易),那么我们需要从前一天的“持有股票且已完成 j-1 次交易”的状态 f[i-1][j-1] 转移而来,并加上今天的股票价格 prices[i]

因此,g[i][j] 的状态转移方程为:

g[i][j]=max(g[i−1][j],f[i−1][j−1]+prices[i])

注意:这里对于 j = 0 的情况,我们需要对其进行处理。

结果

最后,我们遍历g[n-1][j](其中n是价格数组的长度),找到其中的最大值,这就是我们可以获得的最大利润。

class Solution {
public:int maxProfit(int k, vector<int>& prices) {int n = prices.size();// 两个二维数组// f[i][j] : 第i天结束后 完成了j次交易,此时处于买入状态下的最大利润// g[i][j] : 第i天结束后 完成了j次交易,此时处于卖出状态下的最大利润vector<vector<int>> f(n, vector<int>(k + 1, 0));vector<vector<int>> g(n, vector<int>(k + 1, 0));// 初始化f[0][0] = 0 - prices[0];g[0][0] = 0;for (int j = 1; j < k + 1; j++) {f[0][j] = 0 - 0x3f3f3f;g[0][j] = 0 - 0x3f3f3f;}// 填表for (int i = 1; i < n; i++) {for (int j = 0; j <= k; j++) {f[i][j] = max(f[i - 1][j], g[i - 1][j] - prices[i]);// g[i][j] = max(g[i - 1][j], f[i - 1][j - 1] +// prices[i]);//f[i-1][j-1] 因为完成卖出操作后 操作数j++了g[i][j] = g[i - 1][j];if (j > 0)g[i][j] = max(g[i][j], f[i - 1][j - 1] + prices[i]);}}int ret = 0;for (int j = 0; j <= k; j++) {ret = max(ret, g[n - 1][j]);}return ret;}
};


http://www.ppmy.cn/server/109879.html

相关文章

grpc-spring 通信(选型,grpc-ecosystem/grpc-spring)

需求 需要一个在稳定网络环境里高性能且开发和部署成本较小&#xff0c;且多平台&#xff0c;且对视频传输和消息订阅和推送的支持比较好的&#xff0c; 一套环境 先说结论因为结论先得到的&#xff0c; 问AI了&#xff0c; 发现一个新东西gRPC ,看了下非常好。 再说过程&…

【GPT】Coze使用开放平台接口-【2】创建工作流-语音伪造检测工作流

在Coze使用开放平台接口-【1】创建插件&#xff0c;我们已经成功创建了开放平台的插件&#xff0c;也创建了对应的工具。本文档就根据创建好的插件&#xff0c;来创建对应的工作流&#xff0c;来让接口能够用起来。 下面直接用现成的插件快商通AI开放平台&#xff0c;来创建语音…

MFC工控项目实例之七点击下拉菜单弹出对话框

承接专栏《MFC工控项目实例之六CFile添加菜单栏》 1、在SEAL_PRESSUREDlg.h文件中添加代码 class CSEAL_PRESSUREDlg : public CDialog { ...afx_msg void OnTypeManage(); ... } 2、在SEAL_PRESSUREDlg.cpp文件中添加代码 BEGIN_MESSAGE_MAP(CSEAL_PRESSUREDlg, CDialog)//…

3127.构造相同颜色的正方形

1.题目描述 给你一个二维 3 x 3 的矩阵 grid &#xff0c;每个格子都是一个字符&#xff0c;要么是 B &#xff0c;要么是 W 。字符 W 表示白色&#xff0c;字符 B 表示黑色。 你的任务是改变 至多一个 格子的颜色&#xff0c;使得矩阵中存在一个 2 x 2 颜色完全相同的正方形。…

Linux开放防火墙端口

目录 一、使用 firewalld 开启端口二、使用 iptables 开启端口 在 Kylin Linux 上&#xff0c;开启防火墙端口的步骤与其他 Linux 发行版类似。如果 Kylin Linux 使用 firewalld&#xff08;这在许多基于 CentOS 或 RHEL 的发行版上是默认的&#xff09;&#xff0c;你可以按照…

Spring高手之路22——AOP切面类的封装与解析

文章目录 1. AOP是如何收集切面类并封装的&#xff1f;2. Advisor 是什么&#xff0c;它是怎么构建的&#xff1f;2.1 什么是 Advisor2.2 Advisor 的构建&#xff08;源码分析时序图说明&#xff09; 3. TargetSource 的构建和作用3.1 TargetSource 的作用3.2 TargetSource 的构…

分片结果转发: _process_prompt ;if shard.start_layer != 0: 说明不是处理prompt的

目录 分片结果转发: _process_prompt if shard.start_layer != 0: 说明不是处理prompt的 参数 方法体 注意事项 EXO是串行方式的算力共享架构 分片结果转发: _process_prompt 这段代码定义了一个名为 _process_prompt 的异步方法,它属于某个类(尽管类的定义在这段…

基于yolov8的篮球计数检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的篮球计数检测系统是一种高效、精准的目标检测技术&#xff0c;专为篮球比赛中的篮球计数而设计。该系统利用YOLOv8这一先进的深度学习算法&#xff0c;通过实时分析比赛视频或图像&#xff0c;能够迅速且准确地识别并计数篮球的数量。 YOLOv8作为YO…