首页 > 其他分享 >代码随想录——动态规划、股票问题

代码随想录——动态规划、股票问题

时间:2025-01-23 09:42:19浏览次数:1  
标签:状态 股票 代码 随想录 vector prices 卖出 动态 dp

image
https://www.programmercarl.com/动态规划-股票问题总结篇.html#买卖股票的最佳时机含手续费

只能买一次

不断更新最小买入值,不断更新profit=prices[i]-buy

可以买卖多次

动态规划

- 定义dp数组
dp[i][1],dp[i][0]分别表示第i天持有股票时的现金和第i天未持有股票时的现金
- 递推公式
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]);
要么延续前一天相同状态,要么买/卖当前股票
- 初始化
dp[i]需要dp[i-1],因此初始化dp[0]。
dp[0][0]表示第0天没有股票的现金——0
dp[0][1]表示第0天持有股票的现金——为计算正确令为-prices[0]
- 遍历顺序
从前往后遍历

最多买卖两次

动态规划

一天一共就有五个状态,

  • 没有操作
  • 第一次买入
  • 第一次卖出
  • 第二次买入
  • 第二次卖出
    dp[i][j]中 i表示第i天,j为 [0 - 4] 五个状态,dp[i][j]表示第i天状态j所剩最大现金。

代码

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        vector<vector<int>> dp(n,vector<int>(5,0));
        //dp[i][j],i是第i天,j从0-4表示四种状态下持有的现金
        dp[0][0] = 0;//0还没有买过
        dp[0][1] = -prices[0];//1第一次买入股票状态
        dp[0][2] = 0;//2第一次卖掉股票状态
        dp[0][3] = -prices[0];//3第二次买入股票状态
        dp[0][4] = 0;//第二次卖出
        for(int i=1;i<n;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]);
        }
        // 利润最大一定是卖出股票的状态。而dp[i][4]可以=dp[i][2]所以返回4
        return dp[n-1][4];
    }
};

最多买卖k次

动态规划

规律:除了0以外,偶数就是卖出,奇数就是买入。
题目要求是至多有K笔交易,那么j的范围就定义为 2 * k + 1 就可以了。

  • 所以二维dp数组的C++定义为:
    vector<vector<int>> dp(prices.size(), vector<int>(2 * k + 1, 0));
  • 初始化
    在初始化的地方同样要类比j为偶数是卖、奇数是买的状态。

买卖多次,卖出有一天冷冻期

动态规划

具体可以区分出如下四个状态:

  • 状态一今天持有股票状态(今天买入股票,或者是之前就买入了股票然后没有操作,一直持有)
  • 不持有股票状态,这里就有两种卖出股票状态
    • 状态二今天保持卖出股票的状态(两天前就卖出了股票,度过一天冷冻期。或者是前一天就是卖出股票状态,一直没操作)
    • 状态三今天卖出股票
  • 状态四今天为冷冻期状态,但冷冻期状态不可持续,只有一天!
    image

「今天卖出股票」我是没有单独列出一个状态的归类为「不持有股票的状态」,而本题为什么要单独列出「今天卖出股票」 一个状态呢?

因为本题我们有冷冻期,而冷冻期的前一天,只能是 「今天卖出股票」状态,如果是 「不持有股票状态」那么就很模糊,因为不一定是 卖出股票的操作。

初始化

dp数组如何初始化
这里主要讨论一下第0天如何初始化。

如果是持有股票状态(状态一)那么:dp[0][0] = -prices[0],一定是当天买入股票。

保持卖出股票状态(状态二),这里其实从 「状态二」的定义来说 ,很难明确应该初始多少,这种情况我们就看递推公式需要我们给他初始成什么数值。

如果i为1,第1天买入股票,那么递归公式中需要计算 dp[i - 1][1] - prices[i] ,即 dp[0][1] - prices[1],那么大家感受一下 dp[0][1] (即第0天的状态二)应该初始成多少,只能初始为0。想一想如果初始为其他数值,是我们第1天买入股票后 手里还剩的现金数量是不是就不对了。

今天卖出了股票(状态三),同上分析,dp[0][2]初始化为0,dp[0][3]也初始为0。

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int n = prices.size();
        vector<vector<int>> dp(n,vector<int>(5,0));
        //1持有股票 2当天卖 3保持卖出 4冷冻期
        //之前定义0从未买过股票是因为买股票次数有限,现在不限则不需要定义。可以当天买当天卖。
        dp[0][1]=-prices[0];
        for(int i=1;i<n;i++){
            dp[i][1] = max(dp[i-1][4] - prices[i],max(dp[i-1][1],dp[i-1][3] - prices[i]));
            dp[i][2] = dp[i-1][1] + prices[i];
            dp[i][3] = max(dp[i-1][3],dp[i-1][4]);
            dp[i][4] = dp[i-1][2];
        }
        return max(dp[n-1][2],max(dp[n-1][3],dp[n-1][4]));
    }
};

有手续费

卖的时候扣手续费即可

标签:状态,股票,代码,随想录,vector,prices,卖出,动态,dp
From: https://www.cnblogs.com/neromegumi/p/18687131

相关文章

  • 可以在FTP中直接修改网站代码吗?
    是的,您可以在FTP(文件传输协议)中直接修改网站代码。FTP是一种用于在本地计算机和远程服务器之间传输文件的协议,通过FTP客户端软件,您可以连接到网站的服务器,并对网站的文件进行上传、下载和修改等操作。以下是在FTP中修改网站代码的一般步骤:下载并安装FTP客户端软件:您需要在本地......
  • 有哪些常用的网站代码修改软件?
    AdobeDreamweaver:这是一款专业的网页设计和开发工具,支持多种编程语言,如HTML、CSS、JavaScript等。它提供了可视化的编辑界面和代码编辑功能,方便用户进行网站代码的修改和调试。SublimeText:一款轻量级的代码编辑器,具有简洁的界面和强大的功能。它支持多种编程语言,并且可以通过......
  • PHP代码网站链接无法修改怎么办
    如果您在修改PHP代码中的网站链接时遇到问题,可以尝试以下方法:检查代码逻辑:确保您正在修改的是正确的代码位置。有时候,链接可能是通过变量、配置文件或数据库动态生成的,而不是直接写在PHP文件中。查找变量或配置文件:如果链接是通过变量或配置文件生成的,查找相关的变量或配置文件......
  • 修改网站代码的软件
    修改网站代码通常需要使用专业的代码编辑器或集成开发环境(IDE)。以下是一些常见的修改网站代码的软件:VisualStudioCode:一款免费的开源代码编辑器,支持多种编程语言和框架,具有丰富的插件和扩展功能。SublimeText:一款轻量级的代码编辑器,支持多种编程语言和框架,具有快速启动、高......
  • 修改网站代码的浏览器
    修改网站代码通常需要使用专业的代码编辑器或集成开发环境(IDE),而不是浏览器。浏览器主要用于浏览和显示网页,不具备直接修改网站代码的功能。如果您需要在浏览器中查看或调试网站代码,可以使用浏览器的开发者工具。以下是一些常见的浏览器开发者工具:ChromeDevTools:GoogleChrome......
  • 企业网站源代码修改的完整流程与最佳实践
    修改企业网站的源代码是一项需要谨慎对待的任务,既要确保功能的正确实现,又要保障系统的稳定性。以下是具体的步骤和建议:制定详细的修改计划:在开始编码之前,先明确修改的目的和范围。列出所有需要调整的功能点,并评估它们对现有系统的影响。制定时间表,分配责任人,确保项目按期完成。......
  • dotnet 使用 ColorCode 做代码着色器
    本文记录我使用ColorCode开源库简单做一个代码着色器开源库地址:https://github.com/CommunityToolkit/ColorCode-Universal我用的是ColorCode.Core版本,这个版本是无具体UI框架依赖的,于是我就在此基础上,同时做了WPF和Avalonia框架的版本。这两个框架在对ColorCode的......
  • 动态代理
    一、什么是动态代理?现在要给eat方法增加其它功能,例如吃饭之前添加拿筷子,盛饭。在已有的代码中插入,直接修改代码,我们叫做侵入式修改。而在一个成熟的项目中,这样做是很危险的,可能全崩啦!此时想要增加额外的功能而又不能修改原有代码,如何去做呢?此时我们可以找一个代理先帮我们做......
  • 【动态规划】落花人独立,微雨燕双飞 - 8. 01背包问题
    本篇博客给大家带来的是01背包问题之动态规划解法技巧.......
  • 代码随想录算法训练营第一天| 704. 二分查找、27. 移除元素、977.有序数组的平方
    LeetCode7042025-01-2218:30:38星期三代码随想录视频内容简记梳理一下三个比较重要的部分首先是对于整个代码的循环条件,这个很重要判断middle位置在我看来初学也是比较重要一步注意:所有的middle位置判断都是if语句实现的,固定的大于和小于。这个不用纠结一不一样更......