第五十天| 123.买卖股票的最佳时机III、188.买卖股票的最佳时机IV

第四十八天| 121. 买卖股票的最佳时机、122.买卖股票的最佳时机II-CSDN博客

Leetcode 123.买卖股票的最佳时机III

题目链接:123 买卖股票的最佳时机III

题干:给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。

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

思考:动态规划。本题关键在于至多买卖两次,这意味着可以买卖一次,可以买卖两次,也可以不买卖。

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

由于最多可以进行两笔交易。首先不能按 122.买卖股票的最佳时机II 中每次将利润当作本金处理,因为这无法控制交易的次数,因此考虑将这两次交易细节记录下,考虑以下五种状态:

  1. 没有操作 (其实我们也可以不设置这个状态)
  2. 第一次持有股票
  3. 第一次不持有股票
  4. 第二次持有股票
  5. 第二次不持有股票

dp[i][j]中 i表示第i天,j为 [0 - 4] 五个状态,dp[i][j]表示第i天状态j所剩最大现金。

  • 确定递推公式

达到dp[i][1]状态,有两个具体操作:

  • 操作一:第i天买入股票,那么dp[i][1] = dp[i-1][0] - prices[i]
  • 操作二:第i天没有操作,而是沿用前一天买入的状态,即:dp[i][1] = dp[i - 1][1]

并且选较大的,所以 dp[i][1] = max(dp[i-1][0] - prices[i], dp[i - 1][1]);

同理dp[i][2]也有两个操作:

  • 操作一:第i天卖出股票了,那么dp[i][2] = dp[i - 1][1] + prices[i]
  • 操作二:第i天没有操作,沿用前一天卖出股票的状态,即:dp[i][2] = dp[i - 1][2]

所以dp[i][2] = max(dp[i - 1][1] + prices[i], dp[i - 1][2])

同理可推出剩下状态部分:

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

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

  • dp数组如何初始化

状态0表示操作,因此此状态一直为0,则dp[0][0] = 0;

同 121. 买卖股票的最佳时机一样,第0天做第一次买入的操作,dp[0][1] = -prices[0]; 第0天做第一次卖出的操作,dp[0][2] = 0;

至于第0天第二次买入操作,由于第二次买入依赖于第一次卖出的状态,相当于第0天第一次买入了,第一次卖出了,然后再买入一次(第二次买入),那么现在手头上没有现金,只要买入,现金就做相应的减少。所以第二次买入操作,初始化为:dp[0][3] = -prices[0];

同理第二次卖出初始化dp[0][4] = 0;

  • 确定遍历顺序

从递归公式可以看出,一定是从前向后遍历,因为dp[i],依靠dp[i - 1]的数值。

  • 举例推导dp数组

举例:[3,3,5,0,0,3,1,4],dp数组状态如下:

由于第一次卖出股票所得利润当作第二次买入股票的本金,因此最后返回第二次卖出股票所得利润即可。 

代码:

class Solution {
public:int maxProfit(vector<int>& prices) {//dp[i][0]:不操作   //dp[i][1]:第一次持有股票手上的金额     dp[i][2]:第一次不持有股票手上的金额  //dp[i][3]:第二次持有股票手上的金额     dp[i][4]:第二次不持有股票手上的金额vector<vector<int>> dp(prices.size(), vector<int>(5));dp[0][0] = 0;dp[0][1] = - prices[0];dp[0][2] = 0;dp[0][3] = - prices[0];dp[0][4] = 0;for (int i = 1; i < prices.size(); i++) {dp[i][0] = 0;dp[i][1] = max(dp[i - 1][1], - prices[i]);                  //之前已买入股票 或 第i天买入股票(第一次)dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);     //之前已卖出股票 或 第i天卖出股票(第一次)dp[i][3] = max(dp[i - 1][3], dp[i - 1][2] - prices[i]);     //之前已买入股票 或 第i天买入股票(第二次,第一次利润作本金)dp[i][4] = max(dp[i - 1][4], dp[i - 1][3] + prices[i]);     //之前已卖出股票 或 第i天卖出股票(第二次)}return dp[prices.size() - 1][4];}
};

优化:从递推公式可以看出,dp[i]只是依赖于dp[i - 1]的状态。因此只需要记录 当前天的dp状态和前一天的dp状态即可,就是使用滚动数组来节省空间。

代码:

class Solution {
public:int maxProfit(vector<int>& prices) {vector<int> dp(5, 0);dp[1] = - prices[0];dp[3] = - prices[0];for (int i = 1; i < prices.size(); i++) {dp[1] = max(dp[1], dp[0] - prices[i]);dp[2] = max(dp[2], dp[1] + prices[i]);dp[3] = max(dp[3], dp[2] - prices[i]);dp[4] = max(dp[4], dp[3] + prices[i]);}return dp[4];}
};

Leetcode 188.买卖股票的最佳时机IV

题目链接:188 买卖股票的最佳时机IV

题干:给你一个整数数组 prices 和一个整数 k ,其中 prices[i] 是某支给定的股票在第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说,你最多可以买 k 次,卖 k 次。

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

思考:动态规划。本题和上题思路几乎一样,无非是多加几个状态去记录。

代码:

class Solution {
public:int maxProfit(int k, vector<int>& prices) {//dp[i][0]:不操作   //dp[i][2 * j + 1]:第j次持有股票手上的金额     dp[i][2 * j + 2]:第j次不持有股票手上的金额  vector<vector<int>> dp(prices.size(), vector<int>(2 * k + 1, 0));for (int i = 1; i <= 2 * k; i += 2)     //初始化dp[0][i] = - prices[0];for (int i = 1; i < prices.size(); i++) {       //遍历天数for (int j = 1; j <= 2 * k; j += 2) {       //遍历交易dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] - prices[i]);         //之前已买入股票 或 第i天买入股票(第j / 2 + 1次)dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] + prices[i]);     //之前已买入股票 或 第i + 1天买入股票(第j / 2 + 1次,前一次交易利润作本金)}}return dp[prices.size() - 1][2 * k];}
};

自我总结:

理解增加dp状态来记录不同次的交易,仅在循环过程中将前一次利润当本金处理不能控制交易次数。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

centos上部署k8s

环境准备 四台Linux服务器 主机名 IP 角色 k8s-master-94 192.168.0.94 master k8s-node1-95 192.168.0.95 node1 k8s-node2-96 192.168.0.96 node2 habor 192.168.0.77 镜像仓库 三台机器均执行以下命令&#xff1a; 查看centos版本 [rootlocalhost Work]# cat /…

案例介绍:信息抽取技术在汽车销售与分销策略中的应用与实践

一、引言 在当今竞争激烈的汽车制造业中&#xff0c;成功的销售策略、市场营销和分销网络的构建是确保品牌立足市场的关键。作为一名经验丰富的项目经理&#xff0c;我曾领导一个专注于汽车销售和分销的项目&#xff0c;该项目深入挖掘市场数据&#xff0c;运用先进的信息抽取…

2024 DataGrip 激活,分享几个DataGrip 激活的方案

大家好&#xff0c;欢迎来到金榜探云手&#xff01; DataGrip 公司简介 JetBrains 是一家专注于开发工具的软件公司&#xff0c;总部位于捷克。他们以提供强大的集成开发环境&#xff08;IDE&#xff09;而闻名&#xff0c;如 IntelliJ IDEA、PyCharm、和 WebStorm等。这些工…

Android Compose - PlainTooltipBox(已废弃)的替代方案

Android Compose - PlainTooltipBox 的替代方案 TooltipBox(positionProvider TooltipDefaults.rememberPlainTooltipPositionProvider(),tooltip {PlainTooltip {Text(/* tooltip content */)}},state rememberTooltipState(), ) {// tooltip anchorIconButton(onClick {…

齐护ESP32手柄可Arduino编程蓝牙无线游戏手柄Mixly Scratch创客竞赛编程手柄

关于齐护蓝牙手柄 齐护蓝牙手柄&#xff0c;内置蓝牙&#xff0c;专用蓝牙配对码稳定应用&#xff0c;自动无动作后省电休眠&#xff0c;内置锂电池&#xff0c;陀螺仪&#xff0c;双遥杆&#xff08;带按键&#xff09;&#xff0c;及15个多功能按键&#xff0c;人体工艺设计外…

【vue.js】文档解读【day 1】 | 模板语法1

如果阅读有疑问的话&#xff0c;欢迎评论或私信&#xff01;&#xff01; 本人会很热心的阐述自己的想法&#xff01;谢谢&#xff01;&#xff01;&#xff01; 文章目录 模板语法前言文本插值原始HTML属性Attribute绑定动态绑定多个值 模板语法 前言 Vue 使用一种基于 HTML…

【Mysql】InnoDB 中的聚簇索引、二级索引、联合索引

一、聚簇索引 其实之前内容中介绍的 B 树就是聚簇索引。 这种索引不需要我们显示地使用 INDEX 语句去创建&#xff0c;InnoDB 引擎会自动创建。另外&#xff0c;在 InnoDB 引擎中&#xff0c;聚簇索引就是数据的存储方式。 它有 2 个特点&#xff1a; 特点 1 使用记录主键…

WordPress建站入门教程:phpMyAdmin4.8.5出现Fatal error: Unparenthesized错误怎么办?

我们在本地电脑使用小皮面板phpstudy安装phpMyAdmin4.8.5成功后&#xff0c;但是点击【管理】功能打开时却出现如下错误&#xff1a; Fatal error: Unparenthesized a ? b : c ? d : e is not supported. Use either (a ? b : c) ? d : e or a ? b : (c ? d : e) in D:\…

海格里斯HEGERLS助力服装业领域数智化转型 配备7000个托盘位 仓库容量增超110%

近年来&#xff0c;用工荒成为服装制造行业的一大痛点。对此&#xff0c;整个生产体系就要不断地向智能化、自动化生产设备进行转型&#xff0c;甚至在研发设计上都要面向自动化做一些新一代服装制造业的开发。 作为较早入局物流赛道的河北沃克&#xff0c;目前已构建起以AI赋能…

javascript中对包含关系判断介绍

本文将为您详细讲解 JavaScript 中对包含关系的判断&#xff0c;包括数组、字符串等&#xff0c;并提供相应的代码例子。 1. 数组包含关系判断 在 JavaScript 中&#xff0c;数组包含关系判断通常使用 Array.prototype.includes() 方法。这个方法返回一个布尔值&#xff0c;表示…

什么是云游戏?云游戏平台可以运行3A游戏吗?

对于不熟悉游戏行业的人来说&#xff0c;面对云游戏可能会有一个疑问——除了单机游戏&#xff0c;现在所有游戏不都是联网玩吗&#xff1f;云游戏和网络游戏有什么区别&#xff1f; 实际上&#xff0c;云游戏和传统网络游戏有着本质的不同。 传统网络游戏需要玩家先下载并在本…

python网络爬虫教程笔记(1)

系列文章目录 文章目录 系列文章目录前言一、爬虫入门1.爬虫是什么&#xff1f;2.爬虫工作原理3.爬虫基本原理4.工作流程5.HTTP请求6.HTTP响应7.HTTP原理&#xff1a;证书传递、验证和数据加密、解密过程解析8.Urllib.request库的使用9.TCP3次握手&#xff0c;4次挥手过程 总结…

Oracle 的同义词(Synonym) 作用

Oracle 同义词(Synonym) 是数据库对象的一个别名&#xff0c;Oracle 可以为表、视图、序列、过程、函数、程序包等指定一个别名。同义词有两种类型&#xff1a; 私有同义词&#xff1a;拥有 CREATE SYNONYM 权限的用户(包括非管理员用户)即可创建私有同义词&#xff0c;创建的…

【CSP试题回顾】202203-1-未初始化警告

CSP-202203-1-未初始化警告 关键点总结&#xff1a;set 在C中&#xff0c;set 是一个基于平衡二叉树&#xff08;通常是红黑树&#xff09;的关联容器&#xff0c;它包含了一系列唯一的元素&#xff0c;并且这些元素会自动按照特定的排序准则进行排序。以下是 set 中常用的一些…

openGauss环境搭建 | 新手指南

一、搭建准备 openGauss开发需要使用linux环境&#xff0c;先下载远程连接工具Xshell/MobaXterm 。 1. 使用工具连接远程linux服务器&#xff0c;使用root账号远程登录&#xff0c;创建个人账号。 useradd -d /home/xxx -m xxx 2. 设置密码。 passwd xxx 3. 切换到个人账…

主网NFT的发布合约

1.什么是nft? NFT:Non-fungible-token 非同质化货币 2.新建suimove项目 使用sui move new 项目名命令新建sui move项目 sui move new nft_qyx项目结构如下: 3.写nft合约 module qyx123::nft{use sui::object::{Self, UID};use sui::transfer;use sui::tx_context::{Sel…

主备DNS服务器搭建并验证

目录 1. 配置静态网络 2. 配置主备DNS 2.1 DNS备服务器&#xff08;第二个虚拟机&#xff09; 2.2 两个虚拟机操作 2.3 备用服务器&#xff08;第二个虚拟机&#xff09;执行 2.4 两个虚拟机都添加DNS: 3. 验证 3.1 主DNS服务验证: 3.2 备用DNS服务器验证&am…

基于QGIS的研究区域遥感影像裁切下载方法-以岳麓区为例

目录 前言 一、数据说明 1、遥感影像 2、矢量范围 二、按矢量范围导出 1、第一步、导出影像 2、第二步、设置输出格式 3、设置裁切范围 4、设置分辨率 三、按矢量范围掩膜 1、第一步、打开裁剪工具 2、第二步、参数设置 ​编辑 3、执行掩膜 四、webgis支持 1、生成运行…

【自动驾驶坐标系基础】Frenet坐标系和Cartesian坐标系的相互转换

Frenet坐标系和Cartesian坐标系的相互转换 2023.12.12 1 变量含义 Frenet和Cartesian相互转换即 [ s , s ˙ , s , d , d ˙ , d ] ↔ [ X , θ x , κ x , v x , a x ] [s,\dot{s},\ddot{s},d,\dot{d},\ddot{d}] \leftrightarrow[\boldsymbol{X},\theta_x,\kappa_x,v_x,a_…

【Vue】sessionStorage存取数据

一. 需求 1.1 模板 Vab Admin Pro 1.2 组件 ElementUI 1.3 阐述 列表页面搜索【关键词】点击【查询】后&#xff0c;点击【查看】按钮跳转到【详情页】&#xff0c;详情页【返回】【保留原搜索关键词】 原图 搜索查询【关键词】 详情 返回后【保留】【搜索查询关键词…