(动态规划,状态机) 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;
}
};
每天进步一点点~
