题目描述:
标签:数组 动态规划
给定一个数组,它的第 i 个元素是一支给定的股票在第 i 天的价格。
设计一个算法来计算你所能获取的最大利润。你最多可以完成 两笔 交易。
注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
代码:
思路分析:动态规划五部曲
1、确定dp数组以及下标含义,dp[i][0]表示第i天不操作所剩现金,dp[i][1]表示第i天第一次买入所剩现金,dp[i][2]表示第i天第一次卖出所剩现金,dp[i][3]表示第i天第二次买入所剩现金,dp[i][4]表示第i天第二次卖出所剩现金
2、确定递推公式——
①不操作,dp[i][0] = dp[i-1][0]
②第一次买入,两种情况:第i-1天买入了,则dp[i-1][1];第i-1天无操作,则当天买入即dp[i-1][0]-prices[i]。取两者较大值
③第一次卖出,两种情况:第i-1天卖出了,则dp[i-1][2];第i-1天买入了,则当天卖出即dp[i-1][1]+prices[i]。取两者较大值
④第二次买入,两种情况:第i-1天第二次买入,则dp[i-1][3];第i-1天第一次卖出了,则当天买入即dp[i-1][2]-prices[i]。取两者较大值
⑤第二次卖出,两种情况:第i-1天第二次卖出了,则dp[i-1][4];第i-1天第二次买入,则当天卖出即dp[i-1][3]+prices[i]。取两者较大值
3、dp数组初始化,dp[0][1]=-prices[0],dp[0][3]=-prices[0],其他状态dp[i][j]=0
4、确定遍历顺序,从前向后遍历
5、举例推导dp数组
class Solution {
public int maxProfit(int[] prices) {
int n = prices.length;
int[][] dp = new int[n][5];
dp[0][1] = -prices[0];
dp[0][3] = -prices[0];
for(int i = 1;i < n;i++){
dp[i][0] = dp[i-1][0];
dp[i][1] = Math.max(dp[i-1][0]-prices[i],dp[i-1][1]);
dp[i][2] = Math.max(dp[i-1][1]+prices[i],dp[i-1][2]);
dp[i][3] = Math.max(dp[i-1][2]-prices[i],dp[i-1][3]);
dp[i][4] = Math.max(dp[i-1][3]+prices[i],dp[i-1][4]);
}
return dp[n-1][4];
}
}