【动态规划】买卖股票问题

1.一次买入,一次卖出

买卖股票1

1.明确dp[i][0] dp[i][1]含义

dp[i][0]:表示可能在前i天(包括第i天)不持有该股票,产生的最大收益
dp[i][1]:表示可能在前i天(包括第i天)持有该股票,产生的最大收益

2.递推公式

dp[i][0]可能在i天之前卖出,所以的dp[i][0]保持收益,dp[i][0]=dp[i-1][0];
dp[i][0]也可能在第i天卖出,此时dp[i][0]保持最大收益的话,需要在i天之前未卖出产生的最大收益dp[i-1][1]+第i天卖出的收益prices[i].
因为要取dp[i][0]的最大收益,所以
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]);

dp[i][1]可能i天之前已经买入,所以的dp[i][1]保持收益,dp[i][1]=dp[i-1][1];
也可能在第i天买入,则前i天需要未持有股票dp[i-1][0]的最大收益(0)+第i天才买入的收益-prices[i].,由于只能是一次买入,所以不用+前面的前i天需要未持有股票dp[i-1][0]的最大收益(与类型二的区别)
因为要取dp[i][1]的最大收益,所以
dp[i][1]=max(dp[i-1][1],-prices[i]);

3.初始化

dp[0][0]:表示下标为0开始就不持有该股票最大收益为0,没买股票当然是0
dp[0][1]:表示下标为0开始持有该股票最大收益为-prices[i]

dp[0][0]=0;
dp[0][1]-=prices[0];

4.遍历

根据递推公式发现先要初始化前面的值,所以从前到后,dp二维数组的第一个下标范围是股票数组的下标范围,因为0已经初始化,所以从1开始

5.代码实现

class Solution {
public:int maxProfit(vector<int>& prices) {vector<vector<int>>dp(prices.size()+1,vector<int>(2,0));if(prices.size()==1)return 0;dp[0][0]-=prices[0];dp[0][1]=0;for(int i=1;i<prices.size();i++){dp[i][0]=max(dp[i-1][0],-prices[i]);dp[i][1]=max(dp[i-1][1],dp[i-1][0]+prices[i]);}return max(dp[prices.size()-1][0],dp[prices.size()-1][1]);//返回最大值}
};

2.任意买入,任意卖出

买卖股票2

1.明确dp[i][0] dp[i][1]含义

dp[i][0]:表示可能在前i天(包括第i天)不持有该股票,产生的最大收益
dp[i][1]:表示可能在前i天(包括第i天)持有该股票,产生的最大收益

2.递推公式

dp[i][0]可能在i天之前卖出,所以的dp[i][0]保持收益,dp[i][0]=dp[i-1][0];
dp[i][0]也可能在第i天卖出,此时dp[i][0]保持最大收益的话,需要在i天之前未卖出产生的最大收益dp[i-1][1]+第i天卖出的收益prices[i].
因为要取dp[i][0]的最大收益,所以
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]);

dp[i][1]可能i天之前已经买入,所以的dp[i][1]保持收益,dp[i][1]=dp[i-1][1];
==也可能在第i天买入,则前i天需要未持有股票dp[i-1][0]的最大收益+第i天才买入的收益
-prices[i].==因为要取dp[i][1]的最大收益,所以
dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);

3.初始化

dp[0][0]:表示下标为0开始就不持有该股票最大收益为0,没买股票当然是0
dp[0][1]:表示下标为0开始持有该股票最大收益为-prices[i]

dp[0][0]=0;
dp[0][1]-=prices[0];

4.遍历

根据递推公式发现先要初始化前面的值,所以从前到后,dp二维数组的第一个下标范围是股票数组的下标范围,因为0已经初始化,所以从1开始

5.代码实现

class Solution {
public:int maxProfit(vector<int>& prices) {vector<vector<int>>dp(prices.size()+1,vector<int>(2));dp[0][0]=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]);dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);}return max(dp[prices.size()-1][0],dp[prices.size()-1][1]);}
};

3.最多两次买入

买卖股票3

1.明确dp[i][0] dp[i][1] dp[i][2] dp[i][3] dp[i][4]

dp[i][0]:表示前i次包括i无操作,产生的最大收益
dp[i][1]:表示前i次包括i第一次持有股票,产生的最大收益
dp[i][2]:表示前i次包括i第一次卖出股票,产生的最大收益
dp[i][3]:表示前i次包括i第二次持有股票,产生的最大收益
dp[i][4]:表示前i次包括i第二次卖出股票,产生的最大收益

2.递推公式

dp[i][0]如果前i天无操作的话,即不买卖股票,dp[i][0]=dp[i-1][0];

dp[i][1]分两个状态,前i天的某一次第一次持有股票,则dp[i][1]=dp[i-1][1]
第i天第一次持有股票,则需要前i天无操作dp[i-1][0]-第i天买入股票prices[i]
然后取两个状态的最大收益的最大收益
dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);

dp[i][2]可能在前i-1天已经第一次卖出股票dp[i][2]=dp[i-1][2];
也可能在第i天第一次卖出股票,但是要保证前i-1天的某一天第一次持有股票dp[i-1][1]
+第i天第一次卖出股票的收益prices[i].然后取两个状态的最大收益的最大收益
dp[i][2]=max(dp[i-1][2],dp[i-1][1]+prices[i]);

dp[i][3]可能在前i-1天已经第二次持有股票dp[i][3]=dp[i-1][3];
可能是第i天才第二次持有股票,但是必须在前i-1天的某一天第一次卖出股票dp[i-1][2]-第i天第二次买股票prices[i]; dp[i][3]=dp[i-1][2]-price[i];
然后取两个状态的最大收益的最大收益
dp[i][3]=max(dp[i-1][3],dp[i-1][2]-price[i]);

dp[i][4]可能在前i-1天已经第二次卖出股票dp[i][4]=dp[i-1][4];
也可能在第i天才第二次卖出股票,但是要保证在前i-1天的某一天第二次持有股票dp[i-1][3],dp[i][4]=dp[i-1][3]+prices[i];
然后取两个状态的最大收益的最大收益
dp[i][4]=max(dp[i-1][4],dp[i-1][3]+prices[i]);

3.初始化

dp[0][0]=0;//第0天无操作收益为0
dp[0][1]=-price[0];//第0天第一次买入股票收益-price[0]
dp[0][2]=0;//第0天第一次卖出股票可以理解为在一天内买入股票,再卖出股票收益为0
dp[0][3]=-price[0];//第0天第二次买入股票收益-price[0]
dp[0][4]=0;//第0天第二次卖出股票收益为0,在同一天买入卖出同一只支票,收益为0

4.遍历

根据递推公式发现先要初始化前面的值,所以从前到后,dp二维数组的第一个下标范围是股票数组的下标范围,因为0已经初始化,所以从1开始

5.代码实现

class Solution {
public:int maxProfit(vector<int>& prices) {vector<vector<int>>dp(prices.size()+1,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]=dp[i-1][0];//无操作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次买入

该题型和题型3一样
买卖股票4

1.dp[][]含义与题型三相同

2.递推公式

需要k次买入,k次卖出。
使用循环搞定递推公式

for(int j=0;j<2*k;j+=2)
{
dp[i][j+1]=max(dp[i-1][j+1],dp[i-1][j]-prices[i]);//第j+1次已入
dp[i][j+2]=max(dp[i-1][j+2],dp[i-1][j+1]+prices[i]);//第j+1次卖出}

j=0;代表第一次

3.初始化

根据题型3,我们发现每次在买入收益会-price[0];在同一次卖出时在vector中我们会初始化为0

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

4.遍历

    for(int i=1;i<prices.size();i++)for(int j=0;j<2*k;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]);}

5.代码实现

class Solution {
public:int maxProfit(int k, vector<int>& prices) {vector<vector<int>>dp(prices.size()+1,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=0;j<2*k;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];}
};

5.买卖股票含冷冻期

买卖股票冻结期

1.dp[i][0] dp[i][1] dp[i][2] dp[i][3] 的含义

dp[i][0]:表示第i天持有股票,产生的最大收益
dp[i][1]:表示第i天保持卖出股票,产生的最大收益
dp[i][2]:表示第i天卖出股票,产生的最大收益
dp[i][3]:表示第i天出现冻结期,产生的最大收益

2.递推公式

dp[i][0]可能在前i-1天持有股票,收益维持dp[i][0]=dp[i-1];
可能是第i天才买入股票,这种情况分为第i-1天是冷冻期,或者第i-1天是保持卖出股票的状态dp[i][0]=max(dp[i-1][3],dp[i-1][1]);
然后取两个状态的最大收益的最大收益
dp[i][0]=max(dp[i-1],max(dp[i-1][3],dp[i-1][1]));

dp[i][1] 第i-1天可能也是保持卖出股票dp[i][1]=dp[i-1][1];
第i-1天可能是冻结期dp[i][1]=dp[i-1][3];
然后取两个状态的最大收益的最大收益
dp[i][1]=max(dp[i-1][1],dp[i-1][3]);

dp[i][2]第i天卖出股票说明i-1天持有股票+第i天卖出股票
dp[i][2]=dp[i-1][0]+prices[i];

dp[i][3]第i天出现冻结期,则前一天是卖出股票的,dp[i][3]=dp[i-1][2];

3.初始化

dp[0][0]=-price[0]//第0天持有股票
dp[0][2]=0//第0天卖出股票,同一天买入卖出则收益为0
dp[0][1]=0;//第0天出现保持卖出状态,举例你一天内已经买入卖出,此时就是保持卖出状态收益为0,这只是举个例子,这个其实现实中没意义
dp[0][3]=0//...第0天卖出即进入冻结状态,收益也是0,这只是举个例子,这个其实现实中没意义

4.遍历

根据递推公式发现先要初始化前面的值,所以从前到后,dp二维数组的第一个下标范围是股票数组的下标范围,因为0已经初始化,所以从1开始

5.代码实现

class Solution {
public:int maxProfit(vector<int>& prices) {if(prices.size()==0)return 0;vector<vector<int>>dp(prices.size()+1,vector<int>(4,0));dp[0][0]-=prices[0];dp[0][1]=0;dp[0][2]=0;dp[0][3]=0;for(int i=1;i<prices.size();i++){dp[i][0]=max(dp[i-1][0],max(dp[i-1][3]-prices[i],dp[i-1][1]-prices[i]));dp[i][1]=max(dp[i-1][3],dp[i-1][1]);dp[i][2]=dp[i-1][0]+prices[i];dp[i][3]=dp[i-1][2];}return max(dp[prices.size()-1][2],max(dp[prices.size()-1][1],dp[prices.size()-1][3]));//当还持有股票时不会是最大收益,排除一种}
};

6.买卖股票有手续费(与题型二相似)

#股票问题手续费

1.明确dp[i][0] dp[i][1]含义

dp[i][0]:表示可能在前i天(包括第i天)不持有该股票,产生的最大收益
dp[i][1]:表示可能在前i天(包括第i天)持有该股票,产生的最大收益

2.递推公式

dp[i][0]可能在i天之前卖出,所以的dp[i][0]保持收益,dp[i][0]=dp[i-1][0];
dp[i][0]也可能在第i天卖出,此时dp[i][0]保持最大收益的话,需要在i天之前未卖出产生的最大收益dp[i-1][1]+第i天卖出的收益prices[i].
因为要取dp[i][0]的最大收益,所以
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]);

dp[i][1]可能i天之前已经买入,所以的dp[i][1]保持收益,dp[i][1]=dp[i-1][1];
==也可能在第i天买入,则前i天需要未持有股票dp[i-1][0]的最大收益+第i天才买入的收益
-prices[i].==因为要取dp[i][1]的最大收益,所以
dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);

因为每次买卖同一只股票收取一次手续费,则我们可以将手续费夹在买入或者卖出时
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]-fee); // ppppppppppp dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);

dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]); // ppppppppppp dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]-fee);

3.初始化

dp[0][0]:表示下标为0开始就不持有该股票最大收益为0,没买股票当然是0
dp[0][1]:表示下标为0开始持有该股票最大收益为-prices[i]

dp[0][0]=0;
dp[0][1]-=prices[0];

4.遍历

根据递推公式发现先要初始化前面的值,所以从前到后,dp二维数组的第一个下标范围是股票数组的下标范围,因为0已经初始化,所以从1开始

5.代码实现

class Solution {
public:int maxProfit(vector<int>& prices, int fee) {vector<vector<int>>dp(prices.size(),vector<int>(2));dp[0][0]=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.mzph.cn/news/685405.shtml

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

相关文章

android获取sha1

1.cmd在控制台获取 切换到Android Studio\jre\bin目录下执行keytool -list -v -keystore 签名文件路径例如&#xff1a; 2.也可以在android studio中获取 在Terminal中输入命令&#xff1a;keytool -list -v -keystore 签名文件路径获取 获取到的sha1如下&#xff1a;

理解并实现OpenCV中的图像平滑技术

导读 图像模糊&#xff08;也称为图像平滑&#xff09;是计算机视觉和图像处理中的基本操作之一。模糊图像通常是噪声减少、边缘检测和特征提取等应用的第一步。在本博客中&#xff0c;我们将重点介绍如何使用Python中的OpenCV库应用多种模糊技术。 理论概述&#xff1a; 基本…

【报告解析】OpenAI Sora视频模型官方报告全解析 | 效果,能力以及基本原理

省流版 1 核心数据处理将视频数据整合成一个一个的Patch&#xff0c;方便统一训练数据&#xff0c;利用扩散Transformer架构 2 功能效果除了可以实现基础的文生视频外&#xff0c;实际上还有非常惊艳的视频延展&#xff0c;视频编辑&#xff0c;视频连接等多种功能&#xff0…

Android 11.0 SystemUI禁用长按recent键的分屏功能

1.前言 在11.0的系统rom产品定制化中,系统对于多窗口模式默认会有分屏功能的,但是在某些产品中,需要禁用分屏模式,所以需要在导航栏中 禁用长按recent的分屏模式功能,接下来分析下相关分屏模式的实现 2.SystemUI禁用长按recent键的分屏功能的核心类 frameworks\base\…

算法--数论二

这里写目录标题 高斯消元高斯消元求线性方程组用途高斯消元的数学思想例题代码 二级目录 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 一级目录二级目录二级目录二级目录 高斯消元 高斯消元求线性方程组 用途 这个…

VScode写LaTeX配置,实测有效

环境配置请看LaTeX环境配置-TexLive&#xff0c;实测有效http://t.csdnimg.cn/0txlL VScode写LaTeX配置 0.smatra pdf下载 如果使用外部pdf查看器&#xff0c;比如我用的sumatra pdf,官网是Sumatra PDF reader download page 下载对应版本&#xff0c;比如64位&#xff0c;下…

Pandas:DataFrame的完整指南【第82篇—DataFrame】

Pandas&#xff1a;DataFrame的完整指南 Pandas是Python中最流行的数据处理库之一&#xff0c;而其中的DataFrame对象是数据处理的核心。DataFrame为我们提供了一个强大而灵活的数据结构&#xff0c;使得数据的清洗、分析和可视化变得更加简便。在本文中&#xff0c;我们将深入…

【图论经典题目讲解】洛谷 P5304 旅行者

P5304 旅行者 D e s c r i p t i o n \mathrm{Description} Description 给定一个 n n n 个点&#xff0c; m m m 条边的有向图&#xff0c;求解 k k k 个点两两间最短路长度的最小值。 S o l u t i o n \mathrm{Solution} Solution 对于 k k k 个点&#xff0c;可以考虑二…

leetcode hot100爬楼梯

在本题目中&#xff0c;要求爬第n阶有多少种爬法&#xff0c;并且每次只能爬1个或者2个&#xff0c;这明显是动态规划的问题&#xff0c;我们需要用动态规划的解决方式去处理问题。动态规划就是按照正常的顺序由前向后依次推导。而递归则是从结果往前去寻找&#xff08;个人理解…

Android 9.0 禁用adb shell input输入功能

1.前言 在9.0的系统rom产品开发中,在进行一些定制开发中,对于一些adb shell功能需要通过属性来控制禁止使用input 等输入功能,比如adb shell input keyevent 响应输入事件等,所以就需要 熟悉adb shell input的输入事件流程,然后来禁用adb shell input的输入事件功能,接…

docker的常用命令有哪些?

Docker 是一种容器化平台&#xff0c;用于构建、部署和运行应用程序。下面是一些常用的 Docker 命令&#xff1a; 镜像相关命令&#xff1a; docker images&#xff1a;列出本地的镜像。docker pull <镜像名>&#xff1a;从 Docker 仓库中拉取镜像。docker build -t <…

光芒绽放:妙用“GLAD原则”打造标准的数据可视化图表

光芒绽放&#xff1a;妙用“GLAD原则”打造标准的数据可视化图表 文章目录 光芒绽放&#xff1a;妙用“GLAD原则”打造标准的数据可视化图表前言一、可视化工具有哪些&#xff1f;二、那如何做出正确可视化图表 &#xff1f;GLAD原则1.G原则2.L原则3.A原则4.D原则 三、总结最后…

《VulnStack》ATTCK-1

title: 《VulnStack》ATT&CK-1 date: 2024-01-29 14:53:49 updated: 2024-02-14 18:55:49 categories: WriteUp&#xff1a;Cyber-Range excerpt: 主机发现、端口扫描&#xff0c;服务探测&#xff0c;操作系统探测、nmap 漏洞库扫描、网站首页信息泄露、msf 渗透与信息收集…

云计算基础-云计算概念

云计算定义 云计算是一种基于互联网的计算方式&#xff0c;通过这种计算方式&#xff0c;共享的软硬件资源和信息可以按需提供给计算机和其他设备。云计算依赖资源共享以达成规模经济&#xff0c;类似基础设置(如电力网)。 云计算最基本的概念就是云加端&#xff0c;我们有一个…

SW100TSN-百兆车载以太网交换机

更多资讯可以进入官网查看或者联系我们http://www.hdn-vdo.com

基于BP算法的SAR成像matlab仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 BP算法的基本原理 4.2 BP算法的优点与局限性 5.完整工程文件 1.课题概述 基于BP算法的SAR成像。合成孔径雷达&#xff08;SAR&#xff09;是一种高分辨率的雷达系统&#xff0c;能够在各种天气和光…

xtu oj 1090 组合数

Description 2^nC(n,0)C(n,1)…C(n,n)。其中^表示幂&#xff0c;C(n,x)表示组合数&#xff0c;即C(n,x)n!/&#xff08;(n-x)!x!&#xff09;。现在给你n&#xff08;0<n<33&#xff09;&#xff0c;要你输出2^n的组合数之和的表达式 输入 每行一个整数n&#xff0c;如果…

Kafka King 推荐一款漂亮、现代、实用的kafka客户端

Kafka King 一个漂亮、现代、实用的kafka客户端&#xff0c;使用python flet、flutter构建。 Github主页&#xff1a;https://github.com/Bronya0/Kafka-King 下载&#xff1a;https://github.com/Bronya0/Kafka-King/releases 功能清单 查看集群节点列表创建主题&#xf…

波奇学Linux:文件系统打开文件

从文件系统来看打开文件 计算机系统和磁盘交互的大小是4kb 物理内存的4kb&#xff0c;磁盘的4kb文件叫做页帧 磁盘数据块的以4kb为单位。 减少IO的次数&#xff0c;减少访问外设的次数--硬件 基于局部性的原理&#xff0c;预加载机制--软件 操作系统管理内存 操作系统对…

MySQL数据库基础(五):SQL语言讲解

文章目录 SQL语言讲解 一、SQL概述 二、SQL语句分类 1、DDL 2、DML 3、DQL 4、DCL 三、SQL基本语法 1、SQL语句可以单行或多行书写&#xff0c;以分号结尾 2、可使用空格和缩进来增强语句的可读性 3、MySQL数据库的SQL语句不区分大小写&#xff0c;关键字建议使用大写…