买卖股票系列:从状态机彻底吃透动态规划
买卖股票系列:从状态机彻底吃透动态规划
蔚蓝WEILANX哈喽,大家好呀,我是蔚蓝🥰,今天我们要进行一场彻底的「买卖股票」大通关!
之前有很多小伙伴跟我说,股票题一道道刷起来太痛苦了。其实,如果你能看透这背后的「状态机」本质,无论题目怎么变——是限制次数、带冷冻期,还是收手续费,甚至允许「做空」,它们在你的眼里都只是几个状态转来转去的小游戏。
今天这一篇,我把笔记里所有的核心案例和代码都翻了出来,咱们一次性把这块硬骨头啃碎。
1. 股票题的核心:状态转移公式
在进入具体代码之前,请大家在大脑里植入一个万能的思维模型:第 i 天结束后,我处于什么状态?
不管是哪一道股票题,核心公式永远只有这两行(或者是它们的变体):
- 今天空仓 (dp[i][0]) = max(昨天就不持有, 昨天持有 + 今天按市场价卖了)
- 今天持仓 (dp[i][1]) = max(昨天就持有, 「之前的钱」 - 今天买入花的钱)
这里的 「之前的钱」 就是解开所有难题的钥匙。
2. 逐题分析:从简单到「变态」
关卡 1: Stock I (一辈子只能谈一次恋爱)
因为你只能买一次,所以你买入时的起点永远是 0。
1 | // 核心逻辑 |
关卡 2: Stock II (无限次交易)
你可以带着之前赚到的血汗钱继续投。
1 | // 核心逻辑 |
关卡 3: Stock III & IV (有额度限制的交易)
引入了交易次数 k。不仅要看持不持有,还要看这是你的第几次机会。
1 | // Stock IV 三维数组版:dp[天数][次数][状态] |
关卡 4: Stock V (反手做空)
这是最近非常火的一道「博主最爱」题。除了做多(期待涨),你还可以做空(期待跌)。状态从 2 个扩展到 3 个。
- 状态 0:空仓。
- 状态 1:持有多单(Long)。
- 状态 2:持有空单(Short)。
1 | // 平仓逻辑(不持有状态的来源) |
关卡 5: 冷冻期 (给市场一点冷静时间)
卖完后第二天不能买。这时候买入状态 dp[i][0] 只能从「大前天」的状态转移过来。
1 | // 核心逻辑:买入必须跨过一天的冷冻 |
关卡 6: 手续费 (苍蝇腿也是肉)
由于每笔交易都要扣费,咱们只要在卖出的时候狠下心把钱减了就行。
1 | dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i] - fee); |
3. 蔚蓝的通关总结
在考场上,如果你脑子里乱成一团,请默念下面这几点:
- 状态定义第一层级:永远想「我手里有没有股票」。
- 写出三维数组:别急着空间优化,
dp[天][次数][状态]是最稳的。 - 避开 Integer.MIN_VALUE:别用它!用
-1e9这种足够小的数,否则减去房价会溢出。 - 最后返回结果:一定是那些「不持有」状态的最大值。
算法不是为了难为人,而是为了让我们在面对复杂多变的情况时,依然能找到那条最清晰的逻辑线。
🥰 祝大家在这个「状态机」的世界里,都能买到最低位,卖在最高点!

















