题意理解
给定一个数组,每次买入,或者卖出,或者不作。其中卖出后必须等待一天再买入(冻结)。求最大利润。
问题分析
动规 + 状态机
状态分为三种,未持有,持有,冻结,
状态量是前i个股票交易(买入,卖出,冻结三种交易方式)后最大利润值。
进一步细分:当前未持有状态时,前i个股票交易后的最大利润值;当前持有状态时,前i个股票交易后的最大利润值;当前冻结状态时,前i个股票交易后的最大利润值。
状态转移方程:表述前i-1时的状态量和前i状态量之间的关系。
其他
状态机,很好的思路。
链接
int maxProfit(vector<int>& prices) {
int len = prices.size(); //长度
if (len == 0) { //空数组
return 0; //返回0
}
vector<vector<int>> dp(len, vector<int>(3, 0)); //dp
dp[0][0] = 0; //未持有 它的上一个状态是本身,或者冻结状态
dp[0][1] = -prices[0]; //持有 它的上一个状态是本身,或者持有状态
dp[0][2] = INT_MIN; //冻结 它的上一个状态持有,冻结期只有一天,所以不会是它本身
for (int i = 1; i < len; i ++) { //遍历数组
dp[i][0] = max (dp[i - 1][0], dp[i - 1][2]); //当前未持有股票的最大值等于上一个未持有股票时的最大值,和上一个冻结股票时的最大值,之间的较大值
dp[i][1] = max (dp[i - 1][1], dp[i - 1][0] - prices[i]); //当前持有股票的最大值等于上一个持有股票的最大值,和上一个未持有股票时的最大值然后购买股票(付了当前股票的价格)后的差值,之间的较大者
dp[i][2] = dp[i - 1][1] + prices[i]; //当前冻结股票时的最大值等于上一个持有股票时的最大值然后卖出股票(利润增加)后的差值
}
return max (dp[len - 1][0], dp[len - 1][2]); //最终的最大值值可能从未持有,或者冻结两个状态中取较大值
}