Day45 | 动态规划 :状态机DP 买卖股票的最佳时机含冷冻期&&买卖股票的最佳时机含手续费
动态规划应该如何学习?-CSDN博客
本次题解参考自灵神的做法,大家也多多支持灵神的题解
买卖股票的最佳时机【基础算法精讲 21】_哔哩哔哩_bilibili
希望读者在阅读之前先看完这篇博客
Day43 | 动态规划 :状态机DP 买卖股票的最佳时机&&买卖股票的最佳时机II-CSDN博客
动态规划学习:
1.思考回溯法(深度优先遍历)怎么写
注意要画树形结构图
2.转成记忆化搜索
看哪些地方是重复计算的,怎么用记忆化搜索给顶替掉这些重复计算
3.把记忆化搜索翻译成动态规划
基本就是1:1转换
##309.买卖股票的最佳时机含冷冻期
309. 买卖股票的最佳时机含冷冻期 - 力扣(LeetCode)
这题笔者还不够理解,后续再刷的时候再次回顾
思路:
在 122. 买卖股票的最佳时机 II 的基础上,只需修改一处:在计算持有股票的状态时,把 dfs(i−1,0) 改成 dfs(i−2,0)。道理和 198. 打家劫舍 是一样的,因为第 i 天买股票的话第 i−1 天不能卖,只能从第 i−2 天没有股票的状态转移过来。注意 dfs(i−2,0) 并不意味着第 i−2 天一定卖了股票,而是在没有股票下的最优状态。
请注意,这会导致边界条件多了一个 dfs(−2,0)=0
请注意,dfs(−2,1) 是访问不到的,所以下面翻译成递推时,无需初始化这个状态(不需要写 f[0][1]=−∞)。
1.回溯法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Solution { public: int dfs(int i,int status,vector<int>& prices) { if(i<0) if(status==1) return INT_MIN; else return 0; if(status==1) return max(dfs(i-1,1,prices),dfs(i-2,0,prices)-prices[i]); else return max(dfs(i-1,0,prices),dfs(i-1,1,prices)+prices[i]); } int maxProfit(vector<int>& prices) { return dfs(prices.size()-1,0,prices); } };
|
2.记忆化搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { public: int dfs(int i,int status,vector<int>& prices,vector<vector<int>>& dp) { if(i<0) if(status==1) return INT_MIN; else return 0; if(dp[i][status]!=-1) return dp[i][status]; if(status==1) return dp[i][status]=max(dfs(i-1,1,prices,dp),dfs(i-2,0,prices,dp)-prices[i]); else return dp[i][status]=max(dfs(i-1,0,prices,dp),dfs(i-1,1,prices,dp)+prices[i]); } int maxProfit(vector<int>& prices) { vector<vector<int>> dp(prices.size(),vector<int>(2,-1)); return dfs(prices.size()-1,0,prices,dp); } };
|
3.动态规划
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Solution { public: int maxProfit(vector<int>& prices) { vector<vector<int>> dp(prices.size()+2,vector<int>(2,0)); dp[0][1]=INT_MIN/2; dp[1][1]=INT_MIN/2; for(int i=0;i<prices.size();i++) { dp[i+2][1]=max(dp[i+1][1],dp[i][0]-prices[i]); dp[i+2][0]=max(dp[i+1][0],dp[i+1][1]+prices[i]); } return dp[prices.size()+1][0]; } };
|
714.买卖股票的最佳时机含手续费
714. 买卖股票的最佳时机含手续费 - 力扣(LeetCode)
思路:
就是每次卖了股票以后减个手续费就完事
在买卖股票II里面的+prices[i]后面减去fee即可,每次卖完股票赚的利润就是原来的利润减去手续费
1.回溯法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class Solution { public: int dfs(int i,int status,vector<int>& prices,int fee) { if(i<0) if(status==1) return INT_MIN/2; else return 0; if(status==1) return max(dfs(i-1,1,prices,fee),dfs(i-1,0,prices,fee)-prices[i]); else return max(dfs(i-1,0,prices,fee),dfs(i-1,1,prices,fee)+prices[i]-fee); } int maxProfit(vector<int>& prices, int fee) { return dfs(prices.size()-1,0,prices,fee); } };
|
2.记忆化搜索
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class Solution { public: int dfs(int i,int status,vector<int>& prices,int fee,vector<vector<int>>& dp) { if(i<0) if(status==1) return INT_MIN/2; else return 0; if(dp[i][status]!=-1) return dp[i][status]; if(status==1) return dp[i][status]=max(dfs(i-1,1,prices,fee,dp),dfs(i-1,0,prices,fee,dp)-prices[i]); else return dp[i][status]=max(dfs(i-1,0,prices,fee,dp),dfs(i-1,1,prices,fee,dp)+prices[i]-fee); } int maxProfit(vector<int>& prices,int fee) { vector<vector<int>> dp(prices.size(),vector<int>(2,-1)); return dfs(prices.size()-1,0,prices,fee,dp); } };
|
3.动态规划
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Solution { public: int maxProfit(vector<int>& prices,int fee) { vector<vector<int>> dp(prices.size()+1,vector<int>(2,0)); dp[0][0]=0; dp[0][1]=INT_MIN/2; for(int i=0;i<prices.size();i++) { dp[i+1][1]=max(dp[i][1],dp[i][0]-prices[i]); dp[i+1][0]=max(dp[i][0],dp[i][1]+prices[i]-fee); } return dp[prices.size()][0]; } };
|