123. Best Time to Buy and Sell Stock III
DP数组为二维。 第一维是每日,第二维是每日的操作。数组存放本日做过本操作的最大钱数。 操作有5种:
- 不做操作
- 买进第一手
- 卖出第一手
- 买进第二手
- 卖出第二手
要注意每项操作是要依赖于前一项的。
class Solution {
public int maxProfit(int[] prices) {
int[][] dp = new int[prices.length][5];
dp[0][0] = 0;
dp[0][1] = -prices[0];
dp[0][2] = 0;
dp[0][3] = -prices[0];
dp[0][4] = 0;
for(int i=1; i<prices.length; i++) {
dp[i][0] = dp[i-1][0];
dp[i][1] = Math.max(dp[i-1][1], dp[i-1][0] - prices[i]);
dp[i][2] = Math.max(dp[i-1][2], dp[i-1][1] + prices[i]);
dp[i][3] = Math.max(dp[i-1][3], dp[i-1][2] - prices[i]);
dp[i][4] = Math.max(dp[i-1][4], dp[i-1][3] + prices[i]);
}
return dp[prices.length-1][4];
}
}
188. Best Time to Buy and Sell Stock IV
前一题的进阶版。但难度没升多少。总计有2K+1项操作,注意奇数偶数操作的规律。
class Solution {
public int maxProfit(int k, int[] prices) {
int[][] dp = new int[prices.length][2 * k + 1];
int row = prices.length;
int col = 2*k + 1;
for(int i=0; i<col; i++) {
if(i % 2 == 0) {
dp[0][i] = 0;
}
else {
dp[0][i] = -prices[0];
}
}
for(int i=1; i<row; i++) {
dp[i][0] = dp[i-1][0];
for(int j=1; j<col; j++) {
int alt = 0;
if(j%2 == 1) {
alt = -prices[i];
}
else {
alt = prices[i];
}
dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-1] + alt);
}
}
return dp[row-1][col-1];
}
}