递归
- 状态: 怎么描述问题, 当前是持有/未持有状态下, 能获得的最大利润
- 缩小问题规模: 到哪里去/从哪里来
当前状态下,如何做选择才能获利最大? 到哪里去 ```typescript export function maxProfit(prices: number[]): number { // [day…最后一天]最大利润
const cache: number[][] = new Array(prices.length) .fill(0) .map(() => new Array(2).fill(-1));
function backtrack(day: number, state: boolean): number { / state=true表示持有状态 /
// base case if (day >= prices.length) {
return 0;
}
if (cache[day][state ? 0 : 1] !== -1) return cache[day][state ? 0 : 1];
if (state) {
cache[day][state ? 0 : 1] = Math.max(prices[day] + backtrack(day + 1, !state),backtrack(day + 1, state));
} else {
cache[day][state ? 0 : 1] = Math.max(-prices[day] + backtrack(day + 1, !state),backtrack(day + 1, state));
}
return cache[day][state ? 0 : 1]; }
return backtrack(0, false); }
console.log(maxProfit([7, 1, 5, 3, 6, 4]));
<a name="jNmCi"></a># 动态规划- State: 第几天,持有或者非持有状态 的最优价值- 涉及到连续不连续的问题往往需要某个方法来体现。这题目理论上是不连续的问题,但是由于将price预先处理,因此这个不连续其实并不需要考虑,- 当前状态时如何形成的,以及它的最优解 从哪里来- 不连续处理```typescriptfunction maxProfit(prices: number[]): number {// State , status下 第几天的最优解const dp: number[][] = new Array(prices.length).fill(0).map(() => new Array(2).fill(-1));// base casedp[0][0] = 0;dp[0][1] = -prices[0];// make progressfor (let i = 1; i < prices.length; i++) {// 未持有状态 该状态是前面保留的状态或是当天卖出// 当天卖出 卖出的是那一天的{const days = [...Array(i).keys()].filter((day) => prices[day] < prices[i]);const profits = days.map((day) => dp[day][1] + prices[i]);dp[i][0] = Math.max(dp[i - 1][0], Math.max(...profits));}// 持有状态 该状态是前面保留的或是当天买入{dp[i][1] = Math.max(dp[i - 1][1], dp[i][0] - prices[i]);}}console.table(dp);return dp[prices.length - 1][0];}
连续
function maxProfit(prices: number[]): number {// State , status下 第几天的最优解const dp: number[][] = new Array(prices.length).fill(0).map(() => new Array(2).fill(-1));// base casedp[0][0] = 0;dp[0][1] = -prices[0];// make progressfor (let i = 1; i < prices.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][0] - prices[i]);}}return dp[prices.length - 1][0];}
