[日记]LeetCode算法·二十一——动态规划⑥ 股票系列
创始人
2024-05-29 09:25:27
0

1 买卖股票的最佳时机

LeetCode:买卖股票的最佳时机
本题之前已经使用过贪心处理过了,这里使用动态规划思维解决。
本题可以将每天的状态分为持有股票不持有股票,不同状态下每天所剩余的最大现金分别使用dp[i][0]与dp[i][1]表示。

  • 那么针对不持有,分为第i-1天不持有且第i天不操作第i-1天持有且第i天抛出两种情况,那么递推公式为dp[i][0] = max( dp[i-1][0], dp[i-1][1] + prices[i] )
  • 而针对持有,分为第i-1天持有且第i天不操作前i-1天均持有且第i天买入两种情况,dp[i][1] = max( dp[i-1][1], -prices[i] )

值得注意的是,本题只能买入一次股票,因此买入时的现金必然为-prices[i]。

class Solution {
public:int maxProfit(vector& prices) {//dp[i][0]代表第i天持有股票时,所剩余的现金//dp[i][0]意味着【昨天不持有+今天买入】或【昨天持有】//因为只能买入一次,所以【昨天不持有+今天买入】= 0 - prices[i]//故dp[i][0]=max( dp[i-1][0] , dp[i-1][1] - prices[i] )//dp[i][1]代表第i天不持有股票时,所剩余的现金//dp[i][1]意味着【昨天持有+今天卖出】或【昨天不持有+今天不买入】//故dp[i][1] = max( dp[i-1][0] + prices[i] , dp[i-1][1])//因为只用到了dp[i-1],所以可以节省空间//初始化vector dp(2,0);dp[0]=-prices[0];dp[1]=0;for(int i=1;idp[1] = max(dp[1],dp[0]+prices[i]);dp[0] = max(dp[0] ,0 -prices[i]);}return dp[1];}
};

2 买卖股票的最佳时机II

LeetCode:买卖股票的最佳时机II
与上一题的区别在于可以买入多次,因此买入时的现金为dp[i-1][0]-prices[i]

class Solution {
public:int maxProfit(vector& prices) {//使用动态规划//dp[i][0]为【第i天持有时现金】,dp[i][1]为【第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] )vector dp(2,0);dp[0]=-prices[0];dp[1]=0;for(int i=0;iint tmp=dp[0];dp[0] = max(dp[0],dp[1]-prices[i]);dp[1] = max(dp[1],tmp+prices[i]);}return dp[1];}
};

3 买卖股票的最佳时机III

LeetCode:买卖股票的最佳时机III
限定次数的情况,在持有与不持有两种状态的基础上,进一步考虑第一次交易和第二次交易,因此共4种状态。
代码中有详细注释

class Solution {
public:int maxProfit(vector& prices) {//dp[i][0]代表第i天第一次持有时最大现金,dp[i][1]代表第二次持有时最大现金//dp[i][2]代表第一次抛出后第i天不持有时最大现金,dp[i][3]代表第二次抛出后第i天不持有时最大现金//dp[i][0] = max(dp[i-1][0] , 0 - princes[i])//dp[i][1] = max(dp[i-1][1] , dp[i-1][2] - princes[i])//dp[i][2] = max(dp[i-1][2] , dp[i-1][0] + princes[i])//dp[i][3] = max(dp[i-1][3] , dp[i-1][1] + princes[i])//综上,改变顺序应改为dp[3]->dp[1]->dp[2]->dp[0]vector dp(4,0);dp[0] = -prices[0];dp[1] = -prices[0];dp[2] = 0;dp[3] = 0;for(int i = 1 ; idp[3] = max(dp[3],dp[1]+prices[i]);dp[1] = max(dp[1],dp[2]-prices[i]);dp[2] = max(dp[2],dp[0]+prices[i]);dp[0] = max(dp[0],-prices[i]);}return max(dp[2],dp[3]);}
};

4 买卖股票的最佳时机IV

LeetCode:买卖股票的最佳时机IV
和上一题没有区别,值得注意的是规范状态的排列顺序,方便递推公式的写法
另外,因为考虑到第一天进行了若干次的收益为0的模拟买入卖出,所以最后一次(第k次)卖出一定可以得到最多的价值。

class Solution {
public:int maxProfit(int k, vector& prices) {//特殊情况排除if(k==0 || prices.size()<=1)return 0;//dp[i][2*k]代表第i天第k+1次交易时持有,dp[i][2*k+1]代表第i天第k+1次抛出后不持有//dp[i][2*k] = max(dp[i-1][2*k] , dp[i-1][2*k-1] - princes[i])//dp[i][2*k+1] = max(dp[i-1][2*k+1] , dp[i-1][2*k] + princes[i])vector dp(2*k,0);//初始化,持有均为-prices[0]for(int i=0;idp[2*i] = -prices[0];}for(int i=1;ifor(int j=2*k-1;j>=1;j=j-2){dp[j] = max(dp[j] , dp[j-1] + prices[i]);if(j!=1)dp[j-1] = max(dp[j-1] , dp[j-2]-prices[i]);elsedp[j-1] = max(dp[j-1] , -prices[i]);}}return dp[2*k-1];}
};

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

LeetCode:最佳买卖股票时机含冷冻期
考虑冷冻期,因此考虑三种状态:

  • dp[i][0]为第i天持有状态下的最大现金。
  • dp[i][1]为第i天卖出状态下的最大现金(卖出状态也是未持有状态中的一种)。
  • dp[i][2]为第i天不卖出+不持有状态下的最大现金(即明天第i+1天不是冷冻期)
  • 递推公式为:
    • dp[i][0] = max( dp[i-1][0] , dp[i-1][2] - prices[i] )
    • dp[i][1] = dp[i-1][0] + prices[i]
    • dp[i][2] = max( dp[i-1][2] , dp[i-1][1] )
class Solution {
public:int maxProfit(vector& prices) {//dp[i][0]代表第i天持有时的最大现金//dp[i][1]代表第i天【卖出】导致不持有时的最大现金//dp[i][2]代表第i天【不操作】且【不持有】时的最大现金(即第i+1天不是冷冻期的不持有)//dp[i][0] = max( dp[i-1][0] , dp[i-1][2] - prices[i])//dp[i][1] = dp[i-1][0] + prices[i]//dp[i][2] = max( dp[i-1][2] , dp[i-1][1])vector dp(3,0);dp[0]=-prices[0];dp[1]=0;dp[2]=0;for(int i=1;iint tmp=dp[0];dp[0] = max(dp[0],dp[2]-prices[i]);dp[2] = max(dp[2],dp[1]);dp[1] = tmp + prices[i];}return max(dp[1],dp[2]);}
};

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

LeetCode:买卖股票的最佳时机含手续费
手续费融入买入价或者卖出价中,就与问题买卖股票的最佳时机II没有任何区别了。

class Solution {
public:int maxProfit(vector& prices, int fee) {//手续费fee,在每次买入的时候就扣除//dp[0]代表持有,dp[i][0]=max(dp[i-1][0],dp[i-1][1]-princes[i]-fee)//dp[1]代表不持有,dp[i][1] = max(dp[i-1][1] , dp[i-1][0] + princes[i])vector dp(2,0);dp[0]=-prices[0]-fee;dp[1]=0;for(int i = 1 ; iint tmp=dp[0];dp[0] = max( tmp , dp[1] - prices[i] - fee);dp[1] = max( dp[1], tmp+prices[i]);}return dp[1];}
};

7 总结

股票问题就这样了,找好每一天的状态分类递推公式即可。
今天去游泳馆体验了一下,感觉出来后感觉耳朵怪怪的。
——2023.3.5

相关内容

热门资讯

常用商务英语口语   商务英语是以适应职场生活的语言要求为目的,内容涉及到商务活动的方方面面。下面是小编收集的常用商务...
六年级上册英语第一单元练习题   一、根据要求写单词。  1.dry(反义词)__________________  2.writ...
复活节英文怎么说 复活节英文怎么说?复活节的英语翻译是什么?复活节:Easter;"Easter,anniversar...
2008年北京奥运会主题曲 2008年北京奥运会(第29届夏季奥林匹克运动会),2008年8月8日到2008年8月24日在中华人...
英语道歉信 英语道歉信15篇  在日常生活中,道歉信的使用频率越来越高,通过道歉信,我们可以更好地解释事情发生的...
六年级英语专题训练(连词成句... 六年级英语专题训练(连词成句30题)  1. have,playhouse,many,I,toy,i...
上班迟到情况说明英语   每个人都或多或少的迟到过那么几次,因为各种原因,可能生病,可能因为交通堵车,可能是因为天气冷,有...
小学英语教学论文 小学英语教学论文范文  引导语:英语教育一直都是每个家长所器重的,那么有关小学英语教学论文要怎么写呢...
英语口语学习必看的方法技巧 英语口语学习必看的方法技巧如何才能说流利的英语? 说外语时,我们主要应做到四件事:理解、回答、提问、...
四级英语作文选:Birth ... 四级英语作文范文选:Birth controlSince the Chinese Governmen...
金融专业英语面试自我介绍 金融专业英语面试自我介绍3篇  金融专业的学生面试时,面试官要求用英语做自我介绍该怎么说。下面是小编...
我的李老师走了四年级英语日记... 我的李老师走了四年级英语日记带翻译  我上了五个学期的小学却换了六任老师,李老师是带我们班最长的语文...
小学三年级英语日记带翻译捡玉... 小学三年级英语日记带翻译捡玉米  今天,我和妈妈去外婆家,外婆家有刚剥的`玉米棒上带有玉米籽,好大的...
七年级英语优秀教学设计 七年级英语优秀教学设计  作为一位兢兢业业的人民教师,常常要写一份优秀的教学设计,教学设计是把教学原...
我的英语老师作文 我的英语老师作文(通用21篇)  在日常生活或是工作学习中,大家都有写作文的经历,对作文很是熟悉吧,...
英语老师教学经验总结 英语老师教学经验总结(通用19篇)  总结是指社会团体、企业单位和个人对某一阶段的学习、工作或其完成...
初一英语暑假作业答案 初一英语暑假作业答案  英语练习一(基础训练)第一题1.D2.H3.E4.F5.I6.A7.J8.C...
大学生的英语演讲稿 大学生的英语演讲稿范文(精选10篇)  使用正确的写作思路书写演讲稿会更加事半功倍。在现实社会中,越...
VOA美国之音英语学习网址 VOA美国之音英语学习推荐网址 美国之音网站已经成为语言学习最重要的资源站点,在互联网上还有若干网站...
商务英语期末试卷 Part I Term Translation (20%)Section A: Translate ...