首先,分析题干,每天交易结束后,手里有两种情况,一是存在一只股票,二是没有股票,所以定义一个二维数组,分别存放第i天的股票价格和当天的收益情况,定义dp[i][0]表示第i天建议完成后没有股票的最大利润,定义dp[i][1]表示第i天交易完成后手里持有一只股票的最大利润。
为了计算两种情况下的利润情况使用max函数:
即dp[i][0]:
通过遍历的方法对第i天和第i-1天的情况进行加法或差值计算,之后使用max函数选出最大利润。
dp[i][0] = max{dp[i-1][0],dp[i-1][1] + prices[i]};
公式解析:如果本天是交易完后手里没有股票,那么可以分为两种情况:
第一种为前一天也没有股票,所以没有进行交易为前一天的利润情况。
dp[i-1][0];
第二种为前一天结束时手里有一只股票,把他按照今天的价格price[i]卖掉,所以今天的利润就为前一天的收益加今天卖掉股票的收益。
dp[i-1][1] + prices[i]
即dp[i][1]:
dp[i][0] = max{dp[i-1][1],dp[i-1][0] - prices[i]};
按照上述流程考虑:
第一种为前一天手里没有股票,但是今天手里有股票,所以就是今天买入了股票。
dp[i-1][0] - prices[i];
第二种为前一天手里有股票,而今天手里也有股票,因为题干要求不能当天同时进行多笔交易,所以今天没有进行买卖,利润为前一天手里有股票的利润。
dp[i-1][1]
最后返回值:
因为最终按照最后一天将手中的股票卖掉才能利润最大化,所以最后手中没有股票的dp[n - 1][0]才是最大收益,故返回值为没有股票的最后一天的利润。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
int dp[n][2];
dp[0][0] = 0, dp[0][1] = -prices[0];
for (int i = 1; i < n; i++) {
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] - prices[i]);
}
return dp[n - 1][0];
}
};
简化思路:
因为每天的利润之和前一天有关,所以不需要另行开辟二维数组空间来存储,只需要将
dp[i-1][0],dp[i-1][1]进行存储。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
int dp0 = 0, dp1 = -prices[0];
for (int i = 0; i < n; i++) {
int newDp0 = max(dp0, dp1 + prices[i]);
int newDp1 = max(dp1, dp0 - prices[i]);
dp0 = newDp0;
dp1 = newDp1;
}
return dp0;
}
};