算法学习打卡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];
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

OpenGL_Learn12(光照)

续OpenGL_Learn11&#xff08;光照&#xff09;-CSDN博客 1. 镜面高光 和漫反射光照一样&#xff0c;镜面光照也决定于光的方向向量和物体的法向量&#xff0c;但是它也决定于观察方向&#xff0c;例如玩家是从什么方向看向这个片段的。镜面光照决定于表面的反射特性。 我们通…

IDEA没有Add Framework Support解决办法

点击File—>Settings 点击第一个设置快捷键 点击apply和ok即可 我们要点击一下项目&#xff0c;再按快捷键ctrlk 即可

LeetCode(15)分发糖果【数组/字符串】【困难】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 135. 分发糖果 1.题目 n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。相邻两个孩子评分更高的孩子会获…

Unity反编译:IL2CPP 打包输出的cpp文件和dll(程序集)位置、Mono打包输出的dll(程序集)位置

目录 如题&#xff1a;IL2CPP 打包输出的cpp文件和dll位置(并不会出现在APK里) 如题&#xff1a;Mono打包输出的dll位置 校验平台&#xff1a;Android 如题&#xff1a;IL2CPP 打包输出的cpp文件和dll位置(并不会出现在APK里) Unity Assets同级目录下 Temp/StagingArea/Il2…

Django视图层

视图层 django视图层&#xff1a;Django项目下的views.py文件&#xff0c;它的内部是一系列的函数或者是类,用来处理客户端的请求后处理并返回相应的数据 三板斧 HttpResponse # 返回字符串 render # 返回html页面&#xff0c;并且在返回浏览器之前还可以给html文件…

PCA降维Python demo

读这篇15年CVPR的文章&#x1f923;&#x1f923;&#x1f923;&#x1f923;&#x1f923; inproceedings{liu2015sparse,title{Sparse convolutional neural networks},author{Liu, Baoyuan and Wang, Min and Foroosh, Hassan and Tappen, Marshall and Pensky, Marianna},…

第1章 走近Java【深入理解Java虚拟机:JVM高级特性与最佳实践(第三版)】

Java技术体系所包含的内容 Java技术发展的时间线 注释

CFCA国密证书

CFCA是中国金融认证中心的缩写&#xff0c;即China Financial Certification Authority。它是一家经过中国人民银行和国家信息安全机构批准成立的国家级权威安全认证机构&#xff0c;也是国际CA浏览器联盟组织&#xff08;CA/Browser Forum&#xff09;的成员&#xff0c;遵循全…

视频剪辑全自动软件,批量剪辑去重+去水印+背景虚化+ai智能配音

软件介绍 在如今的手机时代&#xff0c;人们拍摄视频的频率越来越高&#xff0c;但大多数人往往因为缺乏专业的剪辑工具而不得不让这些珍贵的视频素材埋没在海洋中。而菜鸟视频剪辑助手的出现&#xff0c;让这些人的生活变得更为便捷。菜鸟视频剪辑助手是一款简单易用的视频剪…

ComfyUI搭建

最近心血来潮想搞下 sd 的东西, 正好赶上腾讯云有活动, 附上个活动链接,有兴趣的小伙伴可以参考下,不用谢我 高性能应用服务HAI 新品内测 一 搭建 首先先选择一个框架, 我想搭建的是 comfyui, 所以选择了Pytorch2.0.0, 里面环境都适配好了 等待个 5-8 分钟就可以了 ,因为需要加…

【微服务专题】Spring启动过程源码解析

目录 前言阅读对象阅读导航前置知识笔记正文一、SpringBoot启动过程源码解析1.1 SpringBoot启动过程源码流程图1.2 流程解析补充1.2.1 SpringApplicationRunListeners&#xff1a;SpringBoot运行过程监听器 学习总结感谢 前言 这部分只是个人的自结&#xff0c;方便后面回来看…

C++11『右值引用 ‖ 完美转发 ‖ 新增类功能 ‖ 可变参数模板』

✨个人主页&#xff1a; 北 海 &#x1f389;所属专栏&#xff1a; C修行之路 &#x1f383;操作环境&#xff1a; Visual Studio 2022 版本 17.6.5 文章目录 &#x1f307;前言&#x1f3d9;️正文1.右值引用1.1.什么是右值引用&#xff1f;1.2.move 转移资源1.3.左值引用 vs …

PowerPoint技巧:如何将一张图片同时加到全部幻灯片里?

想把一张图片加到PPT每一张幻灯片的同一个位置&#xff0c;如果一张一张的添加就太耗时间了&#xff0c;一起来看看如何利用母版快速设置同时添加吧。 首先&#xff0c;打开需要编辑的PPT&#xff0c;在菜单栏依次点击【视图】→【幻灯片母版】&#xff1b; 打开母版后&#x…

Redis Hotkey?3招定位+5招解决

作者总结分享 Redis Hotkey 定位和解决方法的优缺点。 作者&#xff1a;贲绍华&#xff0c;爱可生研发中心工程师&#xff0c;负责项目的需求与维护工作。其他身份&#xff1a;柯基铲屎官。 爱可生开源社区出品&#xff0c;原创内容未经授权不得随意使用&#xff0c;转载请联系…

C语言:简单的用二维数组打印杨氏三角

杨辉三角&#xff0c;又称帕斯卡三角&#xff0c;是一个数学上的规律图形。它的构造规则如下&#xff1a; 每一行的两个端点数字是1。从第三行开始&#xff0c;每个数字是它上方两个数字的和。每一行数字左右对称。 #include<stdio.h> int main() {int arr[50][50];//定…

Windows server 2012 R2系统服务器远程桌面服务激活服务器RD授权分享

Windows server 2012 R2系统服务器远程桌面服务激活服务器RD授权 二、激活服务器&#xff0c;获取许可证服务器ID和许可证密钥包ID三、激活终端服务器四、配置远程桌面会话主机授权服务器 上期我分享了Windows server 2012 R2系统服务器远程桌面服务的安装教程&#xff0c;若是…

贪吃蛇游戏和俄罗斯方块

一、创建新项目 创建一个新的项目&#xff0c;并命名。 创建一个名为images的文件夹用来存放游戏相关图片。 然后再在项目的src文件下创建一个com.xxx.view的包用来存放所有的图形界面类&#xff0c; 创建一个com.xxx.controller的包用来存放启动的入口类(控制类) package …

java初探之代理模式

代理模式 代理模式一般有三种角色&#xff1a; 没有使用代理模式的话可能就会直接去操作真实的对象 加入代理模式就是加入了 隔离 把我们的真实对象与调用者隔离了一下(代理对象) 代理对象的好处&#xff1f; 使用者(client)跟真实的对象是没有直接的交集的。不会直接操作到…

C++二分查找算法:132 模式解法二枚举2

题目及解法一&#xff1a; https://blog.csdn.net/he_zhidan/article/details/134362273 分析 第一步&#xff0c;选择各3对应的1&#xff0c;如果有多个符合对应最小的1&#xff0c;记录num[0,j)中的最小值iMin&#xff0c;如果nums[j]大于iMin&#xff0c;则m3To1 [nums[j…

开源博客项目Blog .NET Core源码学习(6:雪花算法)

Blog .NET项目中有多种数据类生成对象实例时需要唯一标识&#xff0c;一般做法要么使用GUID&#xff0c;也可以保存到数据库时使用数据库表的自增长ID&#xff0c;也可以自定义规则以确保产生不重复的唯一标识&#xff0c;而在Blog .NET项目中使用雪花算法生成唯一标识。   关…