[日记]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

相关内容

热门资讯

超越自己中考满分作文(经典6... 超越自己中考满分作文 篇一超越自己中考作文是考生们最为重视的一项考试,它不仅能够展现考生的语言表达能...
成长类中考满分作文(推荐3篇... 成长类中考满分作文 篇一:《人生的成长之路》人生的成长之路,就像一条曲折而又漫长的山路,充满了各种挑...
2022浙江中考作文范文【推... 2022浙江中考作文范文 篇一题目:我的梦想职业假设你是一名初中生,请你写一篇短文描述一下你的梦想职...
关于中考满分作文附点评【经典... 关于中考满分作文附点评 篇一中国传统节日中秋节中秋节是中国传统的重要节日之一,时间在农历八月十五。人...
教师期中考试成绩分析与反思(... 教师期中考试成绩分析与反思 篇一在教师的职业生涯中,期中考试成绩的分析与反思是提高教学质量和学生学习...
历年安徽中考满分作文满分【优... 历年安徽中考满分作文满分 篇一标题:勇往直前,追求梦想作文内容:在安徽中考的历年满分作文中,有一篇引...
中考满分作文(优选6篇) 中考满分作文 篇一:我眼中的梦想梦想是每个人心中最美好的东西,它给予我们力量和勇气,驱使我们不断努力...
中考数学复习资料【精彩3篇】 中考数学复习资料 篇一近年来,中考数学的题目趋向于注重考查学生对基础知识的掌握和运用能力。在备考过程...
期中考试后的感想300字作文... 期中考试后的感想300字作文 篇一期中考试后的感想期中考试结束了,我终于可以松口气了。翻开试卷,看到...
临沂中考时间安排【推荐3篇】 临沂中考时间安排 篇一近年来,随着中国教育改革的不断深入,中考时间的安排也成为了备受关注的话题。作为...
中考化学复习习题【最新3篇】 中考化学复习习题 篇一化学是中考科目中的一项重要内容,对于学生来说,掌握好化学知识非常关键。为了帮助...
中考提醒:时间物品答题三大注... 中考提醒:时间物品答题三大注意事项 篇一在中考考试中,时间物品答题是非常重要的一部分,对于考生来说,...
中考英语作文精彩结尾(实用3... 中考英语作文精彩结尾 篇一My Dream VacationIn conclusion, my dr...
滑梯的作文 滑梯的作文  “月满则盈亏”,相信这句话已经耳熟能详了。正如当今的社会,各家各户的人都望子‘成龙’,...
中考语文文言文复习【通用3篇... 中考语文文言文复习 篇一文言文是中考语文考试的重点,对于学生来说,熟练掌握文言文的基本知识和技巧是非...
家中考作文(推荐6篇) 家中考作文 篇一我家的宠物狗我家有一只可爱的宠物狗,它是我们家的小宝贝。它叫乐乐,是一只三岁的哈士奇...
成长路上的阳光中考满分作文【... 成长路上的阳光中考满分作文 篇一如何培养积极向上的心态在我们的成长路上,积极向上的心态是非常重要的。...
学生周记(精彩6篇) 学生周记 篇一今天是我入学以来的第一个星期五,也是第一次写周记。这一周对我来说既新鲜又充实。我来到了...
福建三明中考作文题目及:精神... 福建三明中考作文题目及:精神家园 篇一我心灵的港湾精神家园是我们内心深处的一片净土,是我们心灵的港湾...
中考的作文【精选6篇】 中考的作文 篇一:如何做好中考作文中考作文是中学阶段最重要的考试之一,对于学生来说,如何做好中考作文...