买卖股票的通解是使用二维dp数组,为什么需要二维呢?因为需要表示第i天持有股票和不持有股票两种状态的最大值,注意持有不仅仅包括当前买这一种操作,还包括前一天就持有当天不买这种操作。
数组定义
dp[i][0] 第i天持有股票的最大金额;dp[i][1] 第i天不持有股票的最大金额;
递推:
dp[i][0]= max(dp[i-1][0], -price[i]) ->持有的最大利润是前一天持有和当前买的最大值,因为只能交易一次,所以如果当前买的话一定是第一次买,所以利润就是0-price[i];
dp[i][1] = max(dp[i-1][1],dp[i-1][0]+price[i])->不持有的最大利润是前一天不持有和 当天卖中的最大值
初始化:
dp[0][0]=-price[0]; dp[0][1]=0;
遍历:
从i等于1开始遍历
详细代码如下:
class Solution {
public:
int maxProfit(vector<int>& prices) {
//只能买卖一次 需要二维dp数组来表示状态
vector<vector<int>>dp(prices.size(),vector<int>(2,0));
dp[0][0]=-prices[0]; //持有股票的最大金额
dp[0][1]=0; //不持有股票的最大金额
for(int i=1;i<prices.size();i++)
{
dp[i][0] = max(dp[i-1][0],-prices[i]);
dp[i][1] = max(dp[i-1][1],dp[i-1][0]+prices[i]);
}
return dp[prices.size()-1][1];
}
};
这道题和121题目的区别可以多次交易,只要目前手上没有持有股票就可以,因此与上述相比,只需要修改持有股票的递推公式即可:
dp[i][0] = max(dp[i-1][0],dp[i-1][1]-price[i]);
其他与121均相同。
详细代码如下:
class Solution {
public:
int maxProfit(vector<int>& prices) {
//和前一道题的区别就是只要不持有就可以买,而不是只有一次交易机会
vector<vector<int>>dp(prices.size(),vector<int>(2,0));
dp[0][0]=-prices[0]; //持有股票
dp[0][1]=0; //不持有股票
for(int i=1;i<prices.size();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[prices.size()-1][1];
}
};