动态规划三要素
- 状态数组含义
- 初始化含义
- 状态转移方程
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
* 两次交易所能获得的最大收益
* @param prices int整型一维数组 股票每一天的价格
* @return int整型
*/
function maxProfit( prices ) {
// write code here
const n = prices.length;
if(!prices.length) return 0;
// 1、 状态数组
// 每层,可能的五种状态
// 0. 未买入第一次,未买入第二次
// 1. 买入第一次,未买入第二次
// 2. 卖出第一次,未买入第二次
// 3. 卖出第一次,买入第二次
// 4. 卖出第一次,卖出第二次
const dp = new Array(n).fill(0).map(() => new Array(5).fill(-Infinity));// 初始化时我们给一个比较小的数,这样 max 比较时,会选择更大的数,可以少点判断
// 2、 用第一天的状态初始化
// 第一天的状态只可能有两种
dp[0][0] = 0; // 未买入第一次,当前最高收益 0
dp[0][1] = -prices[0]; // 买入第一次,当前最高收益就是买入后剩的钱,因为初始时是没钱的,所以直接为负值
for(let i = 1; i < n; i++) {
// 3、 状态转移方程
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 Math.max(dp[n - 1][4], Math.max(0, dp[n - 1][2])) //有可能第二次是没必要买的,第一次买完后
}
module.exports = {
maxProfit : maxProfit
};