递归
首先描述出问题
第day天,持有or非持有的状态,已经交易times的情况下能获利多少
function maxProfit(prices: number[]): number {const cache: number[][][] = new Array(prices.length).fill(0).map(() => [[-1, -1],[-1, -1],]);function backtrack(day: number, status: number, times: number): number {// base caseif (day >= prices.length || times >= 2) {return 0;}if (cache[day][status][times] !== -1) {return cache[day][status][times];}if (status === 0) {// make progress 到哪里去, 去哪儿// status 未持有cache[day][status][times] = Math.max(-prices[day] + backtrack(day + 1, (status + 1) % 2, times),backtrack(day + 1, status, times));} else {// 持有cache[day][status][times] = Math.max(prices[day] + backtrack(day + 1, (status + 1) % 2, times + 1),backtrack(day + 1, status, times));}return cache[day][status][times];}return backtrack(0, 0, 0);}
动态规划
function maxProfit(prices: number[]): number {const dp: number[][][] = new Array(prices.length).fill(0).map(() => [[0, 0, 0],[0, 0, 0],]);let n = prices.length - 1;// base casedp[0][0][0] = 0;dp[0][0][1] = Number.NEGATIVE_INFINITY;dp[0][0][2] = Number.NEGATIVE_INFINITY;dp[0][1][0] = -prices[0];dp[0][1][1] = Number.NEGATIVE_INFINITY;dp[0][1][2] = Number.NEGATIVE_INFINITY;// make progressfor (let i = 1; i < prices.length; i++) {// 未持有状态 从哪里来{dp[i][0][0] = 0;dp[i][0][1] = Math.max(dp[i - 1][1][0] + prices[i],dp[i - 1][0][1]);dp[i][0][2] = Math.max(dp[i - 1][1][1] + prices[i],dp[i - 1][0][2]);}// 持有状态 从哪里来 前面买入或者当前买入{dp[i][1][0] = Math.max(dp[i - 1][0][0] - prices[i],dp[i - 1][1][0]);dp[i][1][1] = Math.max(dp[i - 1][0][1] - prices[i],dp[i - 1][1][1]);// 已经交易两次还持有,所以不可能dp[i][1][2] = Number.NEGATIVE_INFINITY;}}console.table(dp);return Math.max(...dp[n][0]);}
