当前位置: 首页 > news >正文

leetCode 188.买卖股票的最佳时机 IV 动态规划 + 状态压缩

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

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

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

示例 1:

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

示例 2:

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

 >>思路和分析

这道题目是 的进阶版,这里要求至多有k次交易

>>动规五部曲

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

一天 一共有 j 个 状态 ,dp[i][j] 中 i 表示 第 i 天,j 为[0 - 2*k] 个状态,dp[i][j]表示第 i 天状态 j所剩最大现金

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

"持有" : 不代表就是当天"买入"!可能昨天就买入了,今天保持有的状态

  • ① 我们可以发现,除了0以外,偶数就是不持有,奇数就是持有
  • ② 题目要求是至多有k笔交易,那么j的范围就定义为 2*k+1就可以
vector<vector<int>> dp(prices.size(), vector<int>(2 * k + 1, 0));

2.确定递推公式 

 同理类比剩下的状态,代码如下:

for (int j = 0; j < 2 * k - 1; j += 2) {dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i]);dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);
}

推导思路:

-----------------------------------------------------------
第 i 天 的五种状态
dp[i][0] 不操作dp[i][1] 第一天持有股票时剩下的最大金钱
dp[i][1]         dp[i-1][1]dp[i-1][0] - prices[i]dp[i][2] 第一天不持有股票时剩下的最大金钱
dp[i][2]         dp[i-1][2]dp[i-1][1] + prices[i]dp[i][3] 第二天持有股票时剩下的最大金钱
dp[i][3]         dp[i-1][3]dp[i-1][2] - prices[i]
dp[i][4] 第二天不持有股票时剩下的最大金钱
dp[i][4]         dp[i-1][4]dp[i-1][3] + prices[i]-----------------------------------------------------------
dp[i][j+1]       dp[i-1][j+1]dp[i-1][j] - prices[i]dp[i][j+2]       dp[i-1][j+2]dp[i-1][j+1] + prices[i]dp[i][j+1] = max(dp[i-1][j+1],dp[i-1][j] - prices[i]);
dp[i][j+2] = max(dp[i-1][j+2],dp[i-1][j+1] + prices[i]);
-----------------------------------------------------------

 3.dp数组初始化

dp[0][0] = 0;
dp[0][1] = -prices[0];
dp[0][2] = 0;
dp[0][3] = -prices[0];
dp[0][4] = 0;
...

同理推出dp[0][j]当 j 为奇数时都初始化为 -prices[0]。代码如下:

for (int j = 1; j < 2 * k; j += 2) {dp[0][j] = -prices[0];
}

4.确定遍历顺序

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

5.举例推导dp数组

(1)以输入[1,2,3,4,5],k = 2为例

(2)以输入[3,3,5,0,0,3,1,4],k = 2为例

最后一次卖出,一定是利润最大的,dp[prices.size() - 1][2 * k]即红色部分就是最后求解。 

class Solution {
public:int maxProfit(int k, vector<int>& prices) {if (prices.size() == 0) return 0;vector<vector<int>> dp(prices.size(), vector<int>(2 * k + 1, 0));for (int j = 1; j < 2 * k; j += 2) {dp[0][j] = -prices[0];}for (int i = 1;i < prices.size(); i++) {for (int j = 0; j < 2 * k - 1; j += 2) {dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] - prices[i]);dp[i][j + 2] = max(dp[i - 1][j + 2], dp[i - 1][j + 1] + prices[i]);}}return dp[prices.size() - 1][2 * k];}
};
  • 时间复杂度: O(n * k),其中 n 为 prices 的长度
  • 空间复杂度: O(n * k)

>>状态压缩

class Solution {
public:// 状态压缩int maxProfit(int k, vector<int>& prices) {if (prices.size() == 0) return 0;int len = prices.size();vector<int>dp(2 * k + 1,0);for(int j = 1;j < 2 * k;j += 2) {dp[j] = -prices[0];}for(int i=1;i<len;i++) {for(int j=0;j < 2*k-1;j += 2) {dp[j+1] = max(dp[j+1],dp[j] - prices[i]);dp[j+2] = max(dp[j+2],dp[j+1] + prices[i]);}}return dp[2*k];}
};
  • 时间复杂度: O(n * k),其中 n 为 prices 的长度
  • 空间复杂度: O(k)

参考和推荐文章、视频

动态规划来决定最佳时机,至多可以买卖K次!| LeetCode:188.买卖股票最佳时机4_哔哩哔哩_bilibili

代码随想录 (programmercarl.com) 

来自代码随想录课堂截图:

相关文章:

leetCode 188.买卖股票的最佳时机 IV 动态规划 + 状态压缩

给你一个整数数组 prices 和一个整数 k &#xff0c;其中 prices[i] 是某支给定的股票在第 i 天的价格。 设计一个算法来计算你所能获取的最大利润。你最多可以完成 k 笔交易。也就是说&#xff0c;你最多可以买 k 次&#xff0c;卖 k 次。 注意&#xff1a;你不能同时参与多…...

Lua学习笔记:debug.sethook函数

前言 本篇在讲什么 使用Lua的debug.setHook函数 本篇需要什么 对Lua语法有简单认知 依赖Sublime Text工具 本篇的特色 具有全流程的图文教学 重实践&#xff0c;轻理论&#xff0c;快速上手 提供全流程的源码内容 ★提高阅读体验★ &#x1f449; ♠ 一级标题 &…...

信息化发展74

产业数字化 产业数字化是指在新一代数字科技支撑和引领下&#xff0c;以数据为关键要素&#xff0c;以价值释放为核心&#xff0c;以数据赋能为主线&#xff0c;对产业链上下游的全要素数字化升级、转型和再造的过程。产业数字化作为实现数字经济和传统经济深度融合发展的重要…...

Go-Ldap-Admin | openLDAP 同步钉钉、企业微信、飞书组织架构实践和部分小坑

目录 一、Docker-compose快速拉起demo测试环境 二、原生部署流程 安装MySQL&#xff1a;5.7数据库 安装openLDAP 修改域名&#xff0c;新增con.ldif 创建一个组织 安装OpenResty 下载后端 下载前端 部署后端 部署前端 三、管理动态字段 钉钉 企业微信 飞书 四、…...

elasticsearch+logstash+kibana整合(ELK的使用)第一课

一、安装elasticsearch 0、创建目录&#xff0c;统一放到/data/service/elk 1、下载安装包 wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.1.0-linux-x86_64.tar.gz2、解压 tar -xzvf elasticsearch-7.1.0-linux-x86_64.tar.gz3、新建用户和组…...

宝塔 php修改了php.ini配置不生效

最近在使用hypref&#xff0c;php的版本是7.4 服务器linux&#xff0c;用宝塔安装完php,并装完swoole插件后 安装了swoole后&#xff0c;需要在php.ini中修改一下配置文件 添加 swoole.use_shortnameOff 但是添加了&#xff0c;重启php,依然不生效 解决方法是&#xff1a; 同时…...

Unrecognized option ‘stream_loop‘.(版本不匹配,利用make编译安装)

执行如下命令&#xff1a; ffmpeg -re -stream_loop -1 -i 1.mp4 -vcodec copy -acodec copy -f rtsp -rtsp_transport tcp rtsp://localhost:8554/live1.sdp报如下错误&#xff1a;Unrecognized option ‘stream_loop’. 查看ffmpeg版本&#xff1a;ffmpeg -version 显示&am…...

【考研数学】概率论与数理统计 —— 第三章 | 二维随机变量及其分布(2,常见的二维随机变量及二维变量的条件分布和独立性)

文章目录 引言四、常见的二维随机变量4.1 二维均匀分布4.2 二维正态分布 五、二维随机变量的条件分布5.1 二维离散型随机变量的条件分布律5.2 二维连续型随机变量的条件分布 六、随机变量的独立性6.1 基本概念6.2 随机变量独立的等价条件 写在最后 引言 有了上文关于二维随机变…...

力扣 -- 10. 正则表达式匹配

解题步骤&#xff1a; 参考代码&#xff1a; class Solution { public:bool isMatch(string s, string p) {int ms.size();int np.size();//处理后续映射关系s s;//处理后续映射关系p p;vector<vector<bool>> dp(m1,vector<bool>(n1));//初始化dp[0][0]true…...

Spring源码分析(四) Aop全流程

一、Spring AOP基础概念 1、基础概念 连接点(Join point)&#xff1a;能够被拦截的地方&#xff0c;Spring AOP 是基于动态代理的&#xff0c;所以是方法拦截的&#xff0c;每个成员方法都可以称之为连接点&#xff1b;切点(Poincut)&#xff1a;每个方法都可以称之为连接点&…...

定义现代化实时数据仓库,SelectDB 全新产品形态全面发布

导读&#xff1a;9 月 25 日&#xff0c;2023 飞轮科技产品发布会在线上正式召开&#xff0c;本次产品发布会以 “新内核、新图景” 为主题&#xff0c;飞轮科技 CEO 马如悦全面解析了现代化数据仓库的演进趋势&#xff0c;宣布立足于多云之上的 SelectDB Cloud 云服务全面开放…...

Linux系统编程(七):线程同步

参考引用 UNIX 环境高级编程 (第3版)黑马程序员-Linux 系统编程 1. 同步概念 所谓同步&#xff0c;即同时起步、协调一致。不同的对象&#xff0c;对 “同步” 的理解方式略有不同 设备同步&#xff0c;是指在两个设备之间规定一个共同的时间参考数据库同步&#xff0c;是指让…...

Arcgis克里金插值报错:ERROR 999999: 执行函数时出错。 表名无效。 空间参考不存在。 ERROR 010429: GRID IO 中存在错误

ERROR 999999: 执行函数时出错。 问题描述 表名无效。 空间参考不存在。 ERROR 010429: GRID IO 中存在错误: WindowSetLyr: Window cell size does not match layer cell size. name: c:\users\lenovo\appdata\local\temp\arc2f89\t_t164, adepth: 32, type: 1, iomode: 6, …...

【网络协议】ARP协议

为什么网络需要同时借助MAC地址这种物理地址和IP地址这种逻辑地址进行通信&#xff1f; 尽管目前MAC地址可以通过逻辑的方式进行修改&#xff0c;但它最初是被设计为不可人为更改的硬件地址。虽然MAC地址也可以满足唯一性的要求&#xff0c;但由于它不可由管理员根据需求通过逻…...

安防视频/集中云存储平台EasyCVR(V3.3)部分通道显示离线该如何解决?

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安…...

软件测试经典面试题:如何进行支付功能的测试?

非现金支付时代&#xff0c;非现金支付已经成为了生活不可或缺的一部分&#xff0c;我们只需要一台手机便可走遍全国各地&#xff08;前提是支付宝&#xff0c;微信有钱<00>&#xff09;,那么作为测试人员&#xff0c;支付测试也是非常重要的一环&#xff0c;那么下面我就…...

SolidWorks 入门笔记03:生成工程图和一键标注

默认情况下&#xff0c;SOLIDWORKS系统在工程图和零件或装配体三维模型之间提供全相关的功能&#xff0c;全相关意味着无论什么时候修改零件或装配体的三维模型&#xff0c;所有相关的工程视图将自动更新&#xff0c;以反映零件或装配体的形状和尺寸变化&#xff1b;反之&#…...

【Java】对象内存图多个对象同一内存地址

目录 学生类 单个对象内存图 多个对象指向同一个内存地址 学生类 Student.java如下&#xff1a; package com.面向对象;public class Student {String name;int age;public void work() {System.out.println("开始敲代码...");} }StudentDemo.java如下&#xff…...

Python 笔记05(装饰器的使用)

一 装饰器的使用 (property) property 是 Python 中用于创建属性的装饰器。它的作用是将一个类方法转换为类属性&#xff0c;从而可以像 访问属性一样访问该方法&#xff0c;而不需要使用函数调用的语法。使用 property 主要有以下好处&#xff1a; 封装性和隐藏实现细节&…...

记忆化搜索,901. 滑雪

901. 滑雪 - AcWing题库 给定一个 R 行 C 列的矩阵&#xff0c;表示一个矩形网格滑雪场。 矩阵中第 i行第 j 列的点表示滑雪场的第 i 行第 j列区域的高度。 一个人从滑雪场中的某个区域内出发&#xff0c;每次可以向上下左右任意一个方向滑动一个单位距离。 当然&#xff0…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

HTML前端开发:JavaScript 常用事件详解

作为前端开发的核心&#xff0c;JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例&#xff1a; 1. onclick - 点击事件 当元素被单击时触发&#xff08;左键点击&#xff09; button.onclick function() {alert("按钮被点击了&#xff01;&…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

Linux离线(zip方式)安装docker

目录 基础信息操作系统信息docker信息 安装实例安装步骤示例 遇到的问题问题1&#xff1a;修改默认工作路径启动失败问题2 找不到对应组 基础信息 操作系统信息 OS版本&#xff1a;CentOS 7 64位 内核版本&#xff1a;3.10.0 相关命令&#xff1a; uname -rcat /etc/os-rele…...

基于SpringBoot在线拍卖系统的设计和实现

摘 要 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统&#xff0c;主要的模块包括管理员&#xff1b;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

comfyui 工作流中 图生视频 如何增加视频的长度到5秒

comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗&#xff1f; 在ComfyUI中实现图生视频并延长到5秒&#xff0c;需要结合多个扩展和技巧。以下是完整解决方案&#xff1a; 核心工作流配置&#xff08;24fps下5秒120帧&#xff09; #mermaid-svg-yP…...