基本思想:
DP+贪心+滑动窗口;
该问题感觉更像是一个寻找多个连续递增子序列的问题;
贪心:
贪心属实是没想到;
由于寻找的是多个递增序列中序列的最大差值,所以只需要找相邻递增递增元素的差,累加就可以;
DP:
DP官方给的是二维度DP,只不过第二维度是买入还是卖出;
但是用连续递增子序列的dp思想也可以;
连续递增子序列:
dp[i]保留连续递增的起始坐标,如果遇到非递增,直接重新标记开始;
滑动窗口和该情况类似;
二维dp思想:
dp[i][0]表示第i天进行抛售的收益;
dp[i][1]表示第i天进行买入的收益;
因此,状态转移方程必定为:
但是注意一下初始条件;
dp[0][0]=0;
dp[0][1]=-prices[0];
原因是第一天买入,会直接亏钱,当某天卖出的时候,才是赚钱;
具体代码:
寻找连续递增子序列DP:
class Solution {
public:
int maxProfit(vector<int>& prices) {
if(prices.size()==1)
return 0;
int sum=0;
vector<int>dp(prices.size());
for(int i=1;i<prices.size();i++){
if(prices[i]> prices[i-1]){
dp[i]=dp[i-1];
}else{
dp[i]=i;
sum+=prices[i-1]-prices[dp[i-1]];
}
}
if(dp[dp.size()-1]!=dp.size()-1){
sum+=prices[dp.size()-1]-prices[dp[dp.size()-1]];
}
return sum;
}
};
滑动窗口:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int left=0;
int right=1;
int sum=0;
while(right< prices.size()){
if(prices[right]< prices[right-1]){
sum+=prices[right-1]- prices[left];
left=right;
}
right++;
}
if(left<prices.size()){
sum+=prices[right-1]-prices[left];
}
return sum;
}
};
官方题解DP:
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];
}
};
贪心:
class Solution {
public:
int maxProfit(vector<int>& prices) {
int ans = 0;
int n = prices.size();
for (int i = 1; i < n; ++i) {
ans += max(0, prices[i] - prices[i - 1]);
}
return ans;
}
};