股票问题总结

1|0框架

思路:
明确dp数组的定义,dp[i][k][0]代表 第i天,至多交易K次,并且手上还有股票的最大利润
明确选择:每天都有三种「选择」:买入、卖出、无操作,我们用 buy, sell, rest 表示这三种选择

base casedp[-1][k][0] = dp[i][0][0] = 0 dp[-1][k][1] = dp[i][0][1] = -infinity 状态转移方程: dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1] + prices[i]) dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i])

2|0一次交易最大利润

class Solution { public int maxProfit(int[] prices) { //base case初始状态 dp[-1][0]=0,dp[-1][1]=-99999 int dp_i_0=0,dp_i_1=Integer.MIN_VALUE; //设置一个变量保存前一个状态,使时间复杂度O(1) int n=prices.length; for(int i=0;i<n;i++){ //今天没有持股的情况 dp_i_0=Math.max(dp_i_0,dp_i_1+prices[i]); //今天持股的情况 dp_i_1=Math.max(dp_i_1,-prices[i]); } return dp_i_0; } }

3|0尽可能多的交易

class Solution { public int maxProfit(int[] prices) { int n=prices.length; int dp_i_0=0,dp_i_1=Integer.MIN_VALUE; for(int i=0;i<n;i++){ int tmp=dp_i_0; dp_i_0=Math.max(dp_i_0,dp_i_1+prices[i]); dp_i_1=Math.max(dp_i_1,tmp-prices[i]); } return dp_i_0; } }

4|0最多俩次交易

4|1法1

class Solution { public int maxProfit(int[] prices) { int dp_i10 = 0, dp_i11 = Integer.MIN_VALUE; int dp_i20 = 0, dp_i21 = Integer.MIN_VALUE; for (int price : prices) { dp_i20 = Math.max(dp_i20, dp_i21 + price); dp_i21 = Math.max(dp_i21, dp_i10 - price); dp_i10 = Math.max(dp_i10, dp_i11 + price); dp_i11 = Math.max(dp_i11, -price); } return dp_i20; } }

4|2法2

class Solution { public int maxProfit(int[] prices) { //dp[-1][k][0] = 0 //dp[-1][k][1] = -infinity //dp[i][0][0] = 0 //dp[i][0][1] = -infinity int max_k = 2; int n=prices.length; int[][][] dp = new int[n][max_k + 1][2]; if(n==0) return 0; for (int i = 0; i < n; i++) { for (int k = max_k; k >= 1; k--) { if (i - 1 == -1) { /*处理 base case */ dp[0][k][0]=0; dp[0][k][1]=-prices[0]; continue; } dp[i][k][0] = Math.max(dp[i-1][k][0], dp[i-1][k][1] + prices[i]); dp[i][k][1] = Math.max(dp[i-1][k][1], dp[i-1][k-1][0] - prices[i]); } } // 穷举了 n × max_k × 2 个状态,正确。 return dp[n - 1][max_k][0]; } }

5|0多次交易含冷冻期

class Solution { public int maxProfit(int[] prices) { int n=prices.length; int dp_i_0=0,dp_i_1=Integer.MIN_VALUE; int dp_i_pre=0;//dp[i-2][0] for(int i=0;i<n;i++){ int tmp=dp_i_0; dp_i_0=Math.max(dp_i_0,dp_i_1+prices[i]); dp_i_1=Math.max(dp_i_1,dp_i_pre-prices[i]); dp_i_pre=tmp; } return dp_i_0; } }

6|0多次交易含手续费

class Solution { public int maxProfit(int[] prices, int fee) { int n=prices.length; int dp_i_0=0,dp_i_1=Integer.MIN_VALUE; for(int i=0;i<n;i++){ int tmp=dp_i_0; dp_i_0=Math.max(dp_i_0,dp_i_1+prices[i]); dp_i_1=Math.max(dp_i_1,tmp-prices[i]-fee); } return dp_i_0; } }

__EOF__

本文作者程序员小宇
本文链接https://www.cnblogs.com/treasury/p/12864949.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   程序员小宇  阅读(147)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示