算法学习打卡day45|动态规划:股票问题总结

Leetcode股票问题总结篇

在这里插入图片描述

  • 动态规划的股票问题一共六道题,买卖股票最佳时机和买卖股票手续费都是一个类型的问题,维护好买入和卖出两个状态即可,方法一摸一样。而冷冻期也差不多就是状态多了点,买入、保持卖出、当日卖出、以及冷冻期四个状态。
  • 做题方法还是动态规划五部曲:
    • 明确dp数组含义,这里六道题全部第i天都是手里买入状态或者卖出状态的现金数是多少,这篇文章下标0代表未持有,下标1代表持有。
    • 写出递推公式,下面写了最基本的,其他题的公式都是在这个基础上做了修改的:
      	dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);dp[i][1] = max(dp[i - 1][1], -prices[i]);
      
      • 最佳时机2那道题就是在这个基础上,修改买入时的递推公式为dp[i][1] = max(dp[i - 1][1], dp[i - 1][0]-prices[i - 1]);
      • 最佳时机3那道题是增加两个状态表示第二次买入和卖出:
            dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);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]);
        
      • 最佳时机4那道题是增加到2 * k个状态,那么内层就要变为双层循环为各个状态赋值了。
            dp[i][j] = max(dp[i - 1][j], 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][0] = max(dp[i - 1][0], max(dp[i - 1][3], dp[i - 1][1]) - prices[i]);dp[i][1] = max(dp[i - 1][1], dp[i - 1][3]);dp[i][2] = dp[i - 1][0] + prices[i];dp[i][3] = dp[i - 1][2];
        
      • 含手续费这道题和第二道题一摸一样,在卖出时减去手续费就行。
    • 初始化:每次买入的时候必须初始化为-price[0],其他赋值为0即可。
    • 遍历顺序:由于需要用到 i - 1的资金,所以从前往后遍历

121. 买卖股票的最佳时机

力扣题目链接

代码实现:

int maxProfit(vector<int>& prices) {vector<vector<int>> dp(prices.size() + 1, vector(2, 0));dp[1][0] = 0, dp[1][1] = -prices[0];//二维数组0代表不持有,1代表持有for (int i = 2; i <= prices.size(); ++i) {dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i - 1]);dp[i][1] = max(dp[i - 1][1], -prices[i - 1]);}return dp[prices.size()][0];}
  • 动态规划二维数组滚动数组优化方式:
int maxProfit(vector<int>& prices) {vector<vector<int>> dp(2, vector(2, 0));//只记录当前天和前一天的状态即可dp[0][0] = 0, dp[0][1] = -prices[0];//二维数组0代表不持有,1代表持有for (int i = 1; i < prices.size(); ++i) {dp[i % 2][0] = max(dp[(i - 1) % 2][0], dp[(i - 1) % 2][1] + prices[i]);dp[i % 2][1] = max(dp[(i - 1) % 2][1], -prices[i]);//看实现通过求余,每次取的都是前一个元素值}return dp[(prices.size() + 1) % 2][0];//用+1,因为数组可能为空}
  • 动态规划一维数组实现法,比二维实现更简洁
int maxProfit(vector<int>& prices) {vector<int> dp(2, 0);//只记录当前天的状态即可dp[0] = 0, dp[1] = -prices[0];//0代表不持有,1代表持有for (int i = 1; i < prices.size(); ++i) {dp[0] = max(dp[0], dp[1] + prices[i]);dp[1] = max(dp[1], -prices[i]);}return dp[0];}
  • 贪心法实现(每次更新左边界为最小值,然后不断更新result结果):
int maxProfit(vector<int>& prices) {int low = INT_MAX, result = 0;for (int i = 0; i < prices.size(); ++i) {low = min(low, prices[i]);result = max(result, prices[i] - low);}return result;}

买卖股票的最佳时机2

力扣题目链接
思路:

  • 在上题基础上增加了买卖次数,修改买入时的计算方法即可。

代码实现

  • 普通动态规划想法,直接计算每天的利润(和贪心类似)
int maxProfit(vector<int>& prices) {//dp[i] = max(dp[i - 1], dp[i - 1] + prices[i] - prices[i - 1]);vector<int> dp(prices.size(), 0);for (int i = 1; i < prices.size(); ++i) {dp[i] = max(dp[i - 1], dp[i - 1] + prices[i] - prices[i - 1]);}   return dp[prices.size() - 1];}
  • 用双状态实现的方法(这里用一维数组实现的,也可以是二维)
int maxProfit(vector<int>& prices) {vector<int> dp(2, 0);dp[0] = 0, dp[1] = -prices[0];for (int i = 1; i < prices.size(); ++i) {dp[0] = max(dp[0], dp[1] + prices[i]);dp[1] = max(dp[1], dp[0] - prices[i]);}return dp[0];}
  • 贪心法
int maxProfit(vector<int>& prices) {int profit = 0;for (int i = 1; i < prices.size(); i++) {profit += max(prices[i] - prices[i - 1], 0);}return profit;}
  • 双指针法
int maxProfit(vector<int>& prices) {int profit = 0, buy_index = 0;for (int i = 0; i < prices.size() - 1; i++) {if (prices[i] > prices[i + 1]) {profit += prices[i] - prices[buy_index];buy_index = i + 1;continue;}if (i + 1 == prices.size() - 1) {profit += prices[i + 1] - prices[buy_index];}}return profit;}

买卖股票的最佳时机3

力扣题目链接
思路:

  • 这道题规定只能买卖两次,实现方法上面已经写过了,直接上代码

代码实现

int maxProfit(vector<int>& prices) {vector<vector<int>> dp(prices.size(), vector<int>(5, 0));dp[0][1] = -prices[0], dp[0][3] = -prices[0];//相当于当天买卖一次后再次买入for (int i = 1; i < prices.size(); ++i) {dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);dp[i][2] = max(dp[i - 1][2], dp[i - 1][1] + prices[i]);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]);}return dp[prices.size() - 1][4];}

买卖股票的最佳时机4

力扣题目链接

思路:
买卖次数规定为k次,需要利用循环给每次买卖赋值。

代码实现

int maxProfit(int k, vector<int>& prices) {vector<vector<int>> dp(prices.size(), vector<int>(k * 2 + 1, 0));for (int i = 1; i < 2 * k + 1; i += 2) {dp[0][i] = -prices[0];}for (int i = 1; i < prices.size(); ++i) {for (int j = 1; j <= 2 * k - 1; j += 2) {dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1] - prices[i]);dp[i][j + 1] = max(dp[i - 1][j + 1], dp[i - 1][j] + prices[i]);}}return dp[prices.size() - 1][2 * k];}

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

力扣题目链接
题目描述:
在第二题基础上,增加了冷冻期,需要维护四个状态

代码实现

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

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

力扣题目链接
题目描述:
和第二题基本一样,卖出时减去手续费就行了

代码实现

int maxProfit(vector<int>& prices, int fee) {vector<vector<int>> dp(prices.size(), vector<int>(2, 0));dp[0][1] = -prices[0];for (int i = 1; i < prices.size(); ++i) {dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i] - fee);dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);}return dp[prices.size() - 1][0];}

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

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

相关文章

VueEcharts的使用简解以及常用网站

目录 一&#xff1a;前言 二&#xff1a;实现 1、安装echarts依赖 2、创建图表 1&#xff09;全局引入 2&#xff09;按需引入 三&#xff1a;结尾 一&#xff1a;前言 VueEcharts 是项目开发中可视化的一个重要知识部分。其涵盖了柱状图&#xff0c;饼状图&#xff0c;…

无线终端掉线问题专题

一、终端连接过程 1、通过beacon或者probe帧发现设备 2、accoc和auth过程 3、EAP过程 4、DHCP过程 5、portal过程 6、终端检测wlan是否可以上网 7、正常接入网络 二、终端无法上网 终端无法上网则说明终端在连接过程中某一个环节除了问题 1、发现AP过程&#xff0c;p…

【华为内部资料】《高速数字电路设计教材》(可下载)

与数字技术或软件相比&#xff0c;模拟技术人才的培养和造就仍然需要一定的实践和时间&#xff0c;但无论数字技术发展到任何阶段将永远离不开模拟技术。 由于难度系数较大的原因&#xff0c;有时即便投入很多精力&#xff0c;如果缺乏耐心、毅力和必要的条件&#xff0c;投入…

7个免费的优质图标素材网站,设计师必备!

对于交互设计师和产品经理来说&#xff0c;一套漂亮易用的图标可以算是提高效率的法宝&#xff0c;自己导出一套标准化的图标是一个巨大的工程。如何找到一个既美观又实用又能快速重用的图标&#xff1f;别慌&#xff0c;今天我们整理了7个价值高又好用的图标素材网站&#xff…

多目标跟踪指标

Avg rank This is the rank of each tracker averaged over all present evaluaion measures 这是每个跟踪器在所有现有评估指标上的平均排名。 MOTA Multiple Object Tracking Accuracy This measure combines three error sources &#xff1a;false positives&#xf…

k8s系列-kuboard 该操作平台的使用操作

文章目录 一、相关平台&#xff0c;以及账号和密码镜像打包服务器仓库地址K8s平台数据库mysql 二、平台概述1.集群导入2.集群管理3.名称空间4.访问控制授权5.集群用户操作审计 三、kuboard平台操作手册一、部署服务操作1.名称空间部署2.工作负载部署 一、相关平台&#xff0c;以…

Python数据容器(集合)

集合 1.集合的定义2.集合中常用操作4.常用功能总结5.集合的特点6.练习 思考&#xff1f; 我们目前接触到了列表、元组、字符串三个数据容器了。基本满足大多数的使用场景。为何要学新的集合类型呢&#xff1f; 通过特性分析 列表可以修改、支持重复元素且有序元组、字符串不可修…

【解决方案】危化品厂区安防系统EasyCVR+AI智能监控

危化品属于危险、易燃易爆、易中毒行类&#xff0c;一旦在生产运输过程中发生泄漏后果不堪想象&#xff0c;所以危化品的生产储存更需要严密、精细的监控&#xff0c;来保障危化品的安全。EasyCVRTSINGSEE青犀AI智能分析网关搭建的危化品智能监控方案就能很好的为危化品监管保驾…

错误:ERROR:torch.distributed.elastic.multiprocessing.api:failed

在多卡运行时&#xff0c;会出现错误&#xff08;ERROR:torch.distributed.elastic.multiprocessing.api:failed&#xff09;&#xff0c;但是单卡运行并不会报错&#xff0c;通常在反向梯度传播时多卡梯度不同步。但我是在多卡处理数据进行tokenizer阶段报错&#xff0c;这竟然…

PC6404降压调整器负载大高集成低纹波800mA大电流输出

PC6406是一款由基准电压源、振荡电路、比较器、PWM/PFM 控制电路等构成的CMOS降压DC/DC调整器。利用PWM/PFM自动切换控制电路达到可调占空比&#xff0c;具有全输入电压范围&#xff08;1.8&#xff0d;5.5V&#xff09;内的低纹波、高效率和大输出电流等特点。PC6406内置功率M…

菜单栏图标隐藏管理Bartender 5.0.44

Bartender是一款Mac上的菜单栏图标隐藏管理软件&#xff0c;它可以帮助用户轻松整理和管理菜单栏上的图标&#xff0c;使其更加整洁和有序。 以下是Bartender的一些主要特点和功能&#xff1a; 菜单栏图标隐藏&#xff1a;Bartender允许用户将一些不常用的菜单栏图标隐藏起来&a…

Spring Cloud学习(四)【Nacos配置管理】

文章目录 统一配置管理微服务配置拉取配置热更新多环境配置共享Nacos 集群搭建Nacos集群搭建1.集群结构图2.搭建集群2.1.初始化数据库2.2.下载nacos2.3.配置Nacos2.4.启动2.5.nginx反向代理2.6.优化 统一配置管理 Nacos 可以实现注册中心和配置管理服务 在Nacos中添加配置信息…