假设你有一个数组,它的第i个元素是一支给定的股票在第i天的价格。设计一个算法来找到最大的利润。你最多可以完成两笔交易。
这题与前面的题相比多了一个限定的条件,即我们只能完成两笔交易。用动态规划来做的时候,我们需要记录上当前的状态。一共有五个状态,1,3,5代表了手中是没有股票的,2,4代表了手中有股票。
1是没有进行过交易的,所以其值只能是0。 要达到3和5有两种情况,一是在前一天就没有股票,因此这个值就直接等于前一天的值,二是前一天有股票,今天没有了,说明今天将股票给卖了,值是前一天的值加上今天和昨天股票的差值。最终的结果是在这两种结果中取较大的那个。
2和4,代表有股票,也是有两种情况可以到达的。第一种是前一天也有股票,今天的值就是昨天的值加上这两天股票的差值,第二种是昨天没有持有股票,这时候今天刚刚把股票给买了进来,这时候还没有产生利润,因此直接等于前一天的值就好。最后也是在这两者中取值较大的那一个。
public class Solution {
/**
* @param prices: Given an integer array
* @return: Maximum profit
*/
public int maxProfit(int[] prices) {
// write your code here
int n = prices.length;
if(n == 0)return 0;
int[][] dp = new int [n + 1][6];
for(int i = 2; i <= 5; i++){
dp[0][i] = Integer.MIN_VALUE;
}
dp[0][1] = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= 5; j += 2){
dp[i][j] = dp[i - 1][j];
if(i > 1 && j > 1 && dp[i - 1][j - 1] != Integer.MIN_VALUE){
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - 1] + prices[i - 1] - prices[i - 2]);
}
}
for(int j = 2; j <= 5; j += 2){
dp[i][j] = dp[i - 1][j - 1];
if(i > 1 && dp[i - 1][j] != Integer.MIN_VALUE){
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j] + prices[i - 1] - prices[i -2]);
}
}
}
int res = 0;
for(int j = 1; j <= 5; j += 2){
res = Math.max(res, dp[n][j]);
}
return res;
}
}