public class Solution {
public int rob(TreeNode root) {
int[] res = dfs(root);
return Math.max(res[0], res[1]);
}
private int[] dfs(TreeNode node) {
if (node == null) {
return new int[]{0, 0};
}
int[] left = dfs(node.left);
int[] right = dfs(node.right);
int[] dp = new int[2];
dp[0] = Math.max(left[0], left[1]) + Math.max(right[0], right[1]);
dp[1] = node.val + left[0] + right[0];
return dp;
}
}
dp[i][0]:规定了今天不持股,有以下两种情况: 昨天不持股,今天什么都不做; 昨天持股,今天卖出股票(现金数增加), dp[i][1]:规定了今天持股,有以下两种情况: 昨天持股,今天什么都不做(现金数与昨天一样); 昨天不持股,今天买入股票(注意:只允许交易一次,因此手上的现金数就是当天的股价的相反数)。
class Solution {
public int maxProfit(int[] prices) {
int len = prices.length;
if (len < 2) {
return 0;
}
int[][] dp = new int[len][2];
dp[0][0] = 0;
dp[0][1] = -prices[0];
for (int i = 1; i < len; i++) {
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
dp[i][1] = Math.max(dp[i - 1][1], -prices[i]);
}
return dp[len - 1][0];
}
}
这题的交易次数变成了无数次,其实和上题类似,注意状态转移方程的修改就好。
class Solution {
public int maxProfit(int[] prices) {
if(prices.length == 0 || prices == null){
return 0;
}
int length = prices.length;
int [][] dp = new int [length][2];
dp[0][0]=0;
dp[0][1]=-prices[0];
for(int i=1;i<length;i++){
dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
dp[i][1]=Math.max(dp[i-1][1],dp[i-1][0]-prices[i]);
}
return dp[length-1][0];
}
}
情况三和情况一相似,区别之处是,对于情况三,每天有四个未知变量:T[i][1][0]、T[i][1][1]、T[i][2][0]、T[i][2][1],中间那一维是表示交易第几次,因为这题是要交易两次
public class Solution {
public int maxProfit(int[] prices) {
int len = prices.length;
if (len < 2) {
return 0;
}
int[][][] dp = new int[len][3][2];
dp[0][1][1] = -prices[0];
dp[0][2][1] = Integer.MIN_VALUE;
for (int i = 1; i < len; i++) {
dp[i][1][1] = Math.max(dp[i - 1][1][1], -prices[i]) ;
dp[i][1][0] = Math.max(dp[i - 1][1][0], dp[i - 1][1][1] + prices[i]);
dp[i][2][1] = Math.max(dp[i - 1][2][1], dp[i - 1][1][0] - prices[i]);
dp[i][2][0] = Math.max(dp[i - 1][2][0], dp[i - 1][2][1] + prices[i]);
}
return Math.max(dp[len - 1][1][0], dp[len - 1][2][0]);
}
}
|