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

动态规划之买卖股票问题

🌈🌈😄😄

欢迎来到茶色岛独家岛屿,本期将为大家揭晓动态规划之买卖股票问题 ,做好准备了么,那么开始吧。

🌲🌲🐴🐴

  • 动态规划算法本质上就是穷举「状态」,然后在「选择」中选择最优解。
  • 这个问题的「状态」有三个,第一个是天数,第二个是允许交易的最大次数,第三个是当前的持有状态(即之前说的 rest 的状态,我们不妨用 1 表示持有,0 表示没有持有)。然后我们用一个三维数组就可以装下这几种状态的全部组合:
  • 比如说 dp[3][2][1] 的含义就是:今天是第三天,我现在手上持有着股票,至今最多进行 2 次交易。再比如 dp[2][3][0] 的含义:今天是第二天,我现在手上没有持有股票,至今最多进行 3 次交易。

时刻牢记「状态」的定义,状态 k 的定义并不是「已进行的交易次数」,而是「最大交易次数的上限限制」。如果确定今天进行一次交易,且要保证截至今天最大交易次数上限为 k,那么昨天的最大交易次数上限必须是 k - 1

状态转移方程:

base case:
dp[-1][...][0] = dp[...][0][0] = 0
dp[-1][...][1] = dp[...][0][1] = -infinity状态转移方程:
dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i])
dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])

121. 买卖股票的最佳时机

一、力扣示例

121. 买卖股票的最佳时机 - 力扣(LeetCode)icon-default.png?t=N176https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/

二、解决办法

现在发现 k 都是 1,不会改变,即 k 对状态转移已经没有影响了。
可以进行进一步化简去掉所有 k:
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
dp[i][1] = max(dp[i-1][1], -prices[i])

三、代码实现

class Solution {public int maxProfit(int[] prices) {int n = prices.length;int[][] dp = new int[n][2];for (int i = 0; i < n; i++) {if (i - 1 == -1) {// base casedp[i][0] = 0;dp[i][1] = -prices[i];continue;}dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);dp[i][1] = Math.max(dp[i-1][1], -prices[i]);}return dp[n - 1][0];}
}

 122. 买卖股票的最佳时机 II

一、力扣示例

122. 买卖股票的最佳时机 II - 力扣(LeetCode)icon-default.png?t=N176https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/

二、解决办法

我们发现数组中的 k 已经不会改变了,也就是说不需要记录 k 这个状态了:
dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])

三、代码实现

class Solution {public int maxProfit(int[] prices) {int n=prices.length;int dp[][]=new int[n][2];dp[0][0]=0;dp[0][1]=-prices[0];for(int i=1;i<n;i++){dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);}return dp[n-1][0];}
}

309. 最佳买卖股票时机含冷冻期

一、力扣示例

309. 最佳买卖股票时机含冷冻期 - 力扣(LeetCode)icon-default.png?t=N176https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-cooldown/

二、解决办法

dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
dp[i][1] = max(dp[i-1][1], dp[i-2][0] - prices[i])
解释:第 i 天选择 buy 的时候,要从 i-2 的状态转移,而不是 i-1 。

三、代码实现

class Solution {public int maxProfit(int[] prices) {int n=prices.length;int dp[][]=new int[n][2];dp[0][0] = 0;dp[0][1] = -prices[0];for(int i=1;i<n;i++){if (i - 2 == -1) {// base case 2dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);dp[i][1] = Math.max(dp[i-1][1], -prices[i]);continue;}dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);dp[i][1]=Math.max(dp[i-1][1],dp[i-2][0]-prices[i]);}return dp[n-1][0];}
}

 714. 买卖股票的最佳时机含手续费

一、力扣示例

714. 买卖股票的最佳时机含手续费 - 力扣(LeetCode)icon-default.png?t=N176https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/

二、解决办法

每次交易要支付手续费,只要把手续费从利润中减去即可,改写方程:dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i])
dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i] - fee)
解释:相当于买入股票的价格升高了。
在第一个式子里减也是一样的,相当于卖出股票的价格减小了。

三、代码实现

class Solution {public int maxProfit(int[] prices, int fee) {int n = prices.length;int[][] dp = new int[n][2];for (int i = 0; i < n; i++) {if (i - 1 == -1) {// base casedp[i][0] = 0;dp[i][1] = -prices[i] - fee;continue;}dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i] - fee);}return dp[n - 1][0];}
}

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

一、力扣示例

123. 买卖股票的最佳时机 III - 力扣(LeetCode)icon-default.png?t=N176https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iii/

二、解决办法

原始的状态转移方程,没有可化简的地方
dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i])
dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])

三、代码实现

class Solution {public int maxProfit(int[] prices) {int max_k = 2, n = prices.length;int[][][] dp = new int[n][max_k + 1][2];for (int i = 0; i < n; i++) {for (int k = 1; k <= max_k; k++) {if (i - 1 == -1) {// 处理 base casedp[i][k][0] = 0;dp[i][k][1] = -prices[i];continue;}dp[i][k][0] = Math.max(dp[i-1][k][0], dp[i-1][k][1] + prices[i]);dp[i][k][1] = Math.max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i]);}}// 穷举了 n × max_k × 2 个状态,正确。return dp[n - 1][max_k][0];}}

 

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

一、力扣示例

188. 买卖股票的最佳时机 IV - 力扣(LeetCode)icon-default.png?t=N176https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-iv/

二、解决办法

有了上一题 k = 2 的铺垫,这题应该和上一题的第一个解法没啥区别,你把上一题的 k = 2 换成题目输入的 k 就行了。

但试一下发现会出一个内存超限的错误,原来是传入的 k 值会非常大,dp 数组太大了。那么现在想想,交易次数 k 最多有多大呢?

一次交易由买入和卖出构成,至少需要两天。所以说有效的限制 k 应该不超过 n/2,如果超过,就没有约束作用了,相当于 k 没有限制的情况,而这种情况是之前解决过的。

三、代码实现

class Solution {public int maxProfit(int max_k, int[] prices) {int n = prices.length;if (n <= 0) {return 0;}if (max_k > n / 2) {// 复用之前交易次数 k 没有限制的情况return maxProfit_k_inf(prices);}int[][][] dp = new int[n][max_k + 1][2];// k = 0 时的 base casefor (int i = 0; i < n; i++) {dp[i][0][1] = Integer.MIN_VALUE;dp[i][0][0] = 0;}for (int i = 0; i < n; i++) for (int k = max_k; k >= 1; k--) {if (i - 1 == -1) {// 处理 i = -1 时的 base casedp[i][k][0] = 0;dp[i][k][1] = -prices[i];continue;}dp[i][k][0] = Math.max(dp[i-1][k][0], dp[i-1][k][1] + prices[i]);dp[i][k][1] = Math.max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i]);     }return dp[n - 1][max_k][0];}public int maxProfit_k_inf(int[] prices) {int n = prices.length;int[][] dp = new int[n][2];for (int i = 0; i < n; i++) {if (i - 1 == -1) {// base casedp[i][0] = 0;dp[i][1] = -prices[i];continue;}dp[i][0] = Math.max(dp[i-1][0], dp[i-1][1] + prices[i]);dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]);}return dp[n - 1][0];}
}

 

相关文章:

动态规划之买卖股票问题

&#x1f308;&#x1f308;&#x1f604;&#x1f604; 欢迎来到茶色岛独家岛屿&#xff0c;本期将为大家揭晓动态规划之买卖股票问题 &#xff0c;做好准备了么&#xff0c;那么开始吧。 &#x1f332;&#x1f332;&#x1f434;&#x1f434; 动态规划算法本质上就是穷举…...

MySQL学习笔记之子查询

自连接方式 自连接就是表A连接表A&#xff0c;通过where关键字实现&#xff0c;比如查询工资比Abel高的员工信息&#xff1a; SELECTe2.last_name,e2.salary FROMemployees e1,employees e2 WHEREe1.last_name "Abel" AND e2.salary > e1.salary;子查询 亦称为…...

HCIP-5OSPF域内域间外部路由学习笔记

1、OSPF区域 每个区域都维护一个独立的LSDB。 Area 0是骨干区域&#xff0c;其他区域都必须与此区域相连。 划分OSPF区域可以缩小路由器的LSDB规模&#xff0c;减少网络流量。 区域内的详细拓扑信息不向其他区域发送&#xff0c;区域间传递的是抽象的路由信息&#xff0c;而不…...

【编程实践】简单是好软件的关键:Simplicity is key to good software

Simplicity is key to good software 简单是好软件的关键 目录 Simplicity is key to good software简单是好软件的关键 Complexity is tempting. 复杂性很诱人。 The smallest way to create value创造价值的最小方法 Simple 简单的 Complexity is tempting. 复杂性很诱人…...

Python|贪心|数组|二分查找|贪心|数学|树|二叉搜索树|在排序数组中查找元素的第一个和最后一个位置|计数质数 |将有序数组转换为二叉搜索树

1、在排序数组中查找元素的第一个和最后一个位置&#xff08;数组&#xff0c;二分查找&#xff09; 给定一个按照升序排列的整数数组 nums&#xff0c;和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 如果数组中不存在目标值 target&#xff0c;返回 […...

操作系统——15.FCFS、SJF、HRRN调度算法

这节我们来看一下进程调度的FCFS、SJF、HRRN调度算法 目录 1.概述 2.先来先服务算法&#xff08;FCFS&#xff0c;First Come First Serve&#xff09; 3.短作业优先算法&#xff08;SJF&#xff0c;Shortest Job First&#xff09; 4.高响应比优先算法&#xff08;HRRN&…...

如何防止用户打开浏览器开发者工具?

大家好&#xff0c;我是前端西瓜哥。作为一名前端开发&#xff0c;在浏览一些网页时&#xff0c;有时会在意一些交互效果的实现&#xff0c;会打开开发者工具查看源码实现。 但有些网站做了防窥探处理&#xff0c;打开开发者工具后&#xff0c;会无法再正常进行网页的操作。 …...

C语言-基础了解-12-C数组

C数组 一、C数组 C 语言支持数组数据结构&#xff0c;它可以存储一个固定大小的相同类型元素的顺序集合。数组是用来存储一系列数据&#xff0c;但它往往被认为是一系列相同类型的变量。 数组的声明并不是声明一个个单独的变量&#xff0c;比如 runoob0、runoob1、…、runoo…...

RocksDB 架构

文章目录1、RocksDB 摘要1.1、RocksDB 特点1.2、基本接口1.3、编译2、LSM - Tree2.1、Memtable2.2、WAL2.3、SST2.4、BlockCache3、读写流程3.1、读取流程3.2、写入流程4、LSM-Tree 放大问题4.1、放大问题4.2、compactionRocksDB 是 Facebook 针对高性能磁盘开发开源的嵌入式持…...

MVVM和MVC的区别

首先&#xff0c;MVVM 和 MVC 都是一种设计模式MVCM&#xff08;Model&#xff09;&#xff1a; 模型层。 用于处理应用程序数据逻辑的部分&#xff0c;模型对象负责在数据库中存取数据V &#xff08;View&#xff09;&#xff1a; 视图层。 处理数据显示的部分 &#xff0c;视…...

c++11 标准模板(STL)(std::unordered_map)(三)

定义于头文件 <unordered_map> template< class Key, class T, class Hash std::hash<Key>, class KeyEqual std::equal_to<Key>, class Allocator std::allocator< std::pair<const Key, T> > > class unordered…...

OpenGL环境配置

方法一&#xff1a;1.下载GLFW点击GLFW跳转2.下载后解压3.下载glad&#xff0c;解压后4.用vs2019新建Cmake项目5.在新建的Cmake项目下建立depend文件夹在depend里放置我们下载解压的glad和glfw-3.3.8.bin.WIN646.项目中可以看到我们加进来的文件7.编写我们项目的CMakeLists.txt…...

SpringCloud之 Eureka注册中心

文章目录Eureka注册中心一、服务注册与发现1.1 依赖导入①父工程 SpringCloud 版本管理②Eureka 服务端依赖③Eureka 客户端依赖1.2 服务注册①创建 Eureka 服务端的主类②设置 Eureka 服务端的配置文件③设置 Eureka 客户端的配置文件④关闭自我保护机制1.3 服务发现①远程调用…...

Linux入门篇-用户管理

简介 linux基本的用户管理。 ⽤户的管理(切换到root) ⽤户的添加&#xff08;useradd&#xff09; ⽤户的删除&#xff08;userdel&#xff09; ⽤户的修改&#xff08;usermod&#xff09; ⽤户的查看&#xff08;查看/etc/passwd&#xff09; id⽤户组的管理(切换到root) …...

G. Special Permutation(构造)

1、题目 G. Special Permutation 这道题的意思是给我们从111到nnn的排列&#xff0c;然后我们对这个排列的顺序上进行调换&#xff0c;需要满足的条件是任意两个相邻元素的绝对值的差满足条件&#xff1a;2≤∣pi−pi1∣≤42\leq |p_i-p_{i 1}|\leq 42≤∣pi​−pi1​∣≤4 …...

QML动态对象管理

QML中有多种方式来动态创建和管理QML对象&#xff1a; Loader &#xff08;加载器&#xff09;Repeater&#xff08;复制器&#xff09;ListView&#xff0c;GridWiew&#xff0c;PethView&#xff08;视图&#xff09; &#xff08;之后会介绍&#xff09;使用加载器&#xff…...

cmake入门03 -自定义find外部库

自定义检测外部库使用pkg-config查找库搜索.pc配置文件cmake函数链接到库自定义find库检测外部库的便捷方法&#xff1a;使用CMake自带的find-module使用<package>Config.cmake, <package>ConfigVersion.cmake和<package>Targets.cmake。这些文件由软件商提供…...

Dubbo源码解析-——服务导出

前言 在之前我们讲过Spring和Dubbo的集成&#xff0c;我们在服务上标注了DubboService的注解&#xff0c;然后最终Dubbo会调用到ServiceBean#export方法中&#xff0c;本次我们就来剖析下服务导出的全流程。 一、前置回顾 由于ServiceBean实现了ApplicationListener接口&…...

vue+django+neo4j 基于知识图谱红楼梦问答系统

vuedjangoneo4j 基于知识图谱红楼梦问答系统 项目背景 知识图谱是一种以图谱形式描述客观世界中存在的各种实体、概念及其关系的技术, 广泛应用于智能搜索、自动问答和决策支持等领域. 可视分析技术可以将抽象的知识图谱映射为图形元素, 帮助用户直观地感知和分析数据, 从而提…...

2023年全国最新食品安全管理员精选真题及答案13

百分百题库提供食品安全管理员考试试题、食品安全员考试预测题、食品安全管理员考试真题、食品安全员证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 121.关于食品召回的说法&#xff0c;以下表述不正确的是&#xff08;&am…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

测试微信模版消息推送

进入“开发接口管理”--“公众平台测试账号”&#xff0c;无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息&#xff1a; 关注测试号&#xff1a;扫二维码关注测试号。 发送模版消息&#xff1a; import requests da…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序

一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

安宝特案例丨Vuzix AR智能眼镜集成专业软件,助力卢森堡医院药房转型,赢得辉瑞创新奖

在Vuzix M400 AR智能眼镜的助力下&#xff0c;卢森堡罗伯特舒曼医院&#xff08;the Robert Schuman Hospitals, HRS&#xff09;凭借在无菌制剂生产流程中引入增强现实技术&#xff08;AR&#xff09;创新项目&#xff0c;荣获了2024年6月7日由卢森堡医院药剂师协会&#xff0…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...