(动态规划,状态机) leetcode 股票问题
https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
思路参考链接:
个问题的「状态」有三个,第一个是天数,第二个是允许交易的最大次数,第三个是当前的持有状态(即之前说的 rest 的状态,我们不妨用 1 表示持有,0 表示没有持有)。然后我们用一个三维数组就可以装下这几种状态的全部组合:
class Solution { public: int maxProfit(vector<int>& prices) { int dp_i_0 = 0, dp_i_1 = INT_MIN; //base case for(int i=0; i<prices.size(); ++i){ dp_i_0 = max(dp_i_0, dp_i_1+prices[i]); dp_i_1 = max(dp_i_1, -prices[i]); } return dp_i_0; } };
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/
class Solution { public: int maxProfit(vector<int>& prices) { int dp_i_0 = 0, dp_i_1 = INT_MIN; for(int i=0; i<prices.size(); ++i){ int temp = dp_i_0; dp_i_0 = max(dp_i_0, dp_i_1 + prices[i]); dp_i_1 = max(dp_i_1, temp-prices[i]); } return dp_i_0; } };
https://leetcode.com/problems/best-time-to-buy-and-sell-stock-with-cooldown/
含冷冻期(cooldown) 一天的意思是在卖出股票后,要rest一天后,才能买入。
class Solution { public: int maxProfit(vector<int>& prices) { int dp_i_0 = 0, dp_i_1 = INT_MIN; int dp_pre_0 = 0; //dp[i-2][0] for(int i=0; i<prices.size(); ++i){ int temp = dp_i_0; dp_i_0 = max(dp_i_0, dp_i_1+prices[i]); dp_i_1 = max(dp_i_1, dp_pre_0 - prices[i]); //第i天持有股票,只能在i-2天及以前买进 dp_pre_0 = temp; } return dp_i_0; } };
class Solution { public: int maxProfit(vector<int>& prices, int fee) { int dp_i_0 = 0, dp_i_1 = INT_MIN; for(int i=0; i<prices.size(); ++i){ int temp = dp_i_0; dp_i_0 = max(dp_i_0, dp_i_1+prices[i]); dp_i_1 = max(dp_i_1, temp-prices[i]-fee); } return dp_i_0; } };
class Solution { public: int maxProfit(vector<int>& prices) { int dp_i_1_0 = 0, dp_i_1_1 = INT_MIN; int dp_i_2_0 = 0, dp_i_2_1 = INT_MIN; for(int price: prices){ dp_i_2_0 = max(dp_i_2_0, dp_i_2_1 + price); dp_i_2_1 = max(dp_i_2_1, dp_i_1_0 - price); dp_i_1_0 = max(dp_i_1_0, dp_i_1_1 + price); dp_i_1_1 = max(dp_i_1_1, - price); } return dp_i_2_0; } };
class Solution { public: int maxProfit(int k, vector<int>& prices) { int n = prices.size(); if(k > n/2) return maxprofit(prices); vector<int> sold(k+1, 0), bought(k+1, INT_MIN); for(int price: prices){ for(int i = 1; i<=k; ++i){ sold[i] = max(sold[i], bought[i] + price); //sold[i]指当前操作为卖出,即不持有股h bought[i] = max(bought[i], sold[i-1] - price); //bought[i]指当前操作为买进,即持有股票 } } return sold[k]; } int maxprofit(vector<int>& prices){ //k = +infinity int dp_i_0 = 0, dp_i_1 = INT_MIN; for(int p : prices){ int temp = dp_i_0; dp_i_0 = max(dp_i_0, dp_i_1 + p); dp_i_1 = max(dp_i_1, temp - p); } return dp_i_0; } };