动态规划
var maxProfit = function (k, prices) {
let n = prices.length
if (k >= Math.floor(n / 2)) {
let profit = 0
for (let i = 1; i < n; ++i) {
if (prices[i] > prices[i - 1]) {
profit += (prices[i] - prices[i - 1])
}
}
return profit
}
// dp[i][j] 表示第i天进行j次操作获取的最大利润
let dp = Array.from({ length: n }, () => Array(k + 1).fill(0))
for (let j = 1; j <= k; ++j) {
let profit = -prices[0]
for (let i = 1; i < n; ++i) {
// 卖出操作
dp[i][j] = Math.max(dp[i - 1][j], prices[i] + profit)
// 买入操作
profit = Math.max(profit, dp[i][j - 1] - prices[i])
}
}
return dp[n - 1][k]
};
18行代码
dp[i][j] = Math.max(dp[i - 1][j], prices[i] + profit)
-
dp[i][j]表示在第i天时,最多允许j次交易,能获得的最大利润。 -
这里我们有两个选择:
-
不交易:即保持前一天的最大利润
dp[i-1][j],也就是今天不进行交易。 -
卖出股票:假设今天是卖出的一天,那么我们需要加上之前买入时的最大潜在收益
maxProfit,以及今天卖出时的价格prices[i]。因此利润是prices[i] + maxProfit。
maxProfit表示在之前某一天买入的最大利润(包括买入前的交易次数为j-1的最大利润,之后再加上今天的卖出)。
-
最终,通过 Math.max(dp[i-1][j], prices[i] + profit) 比较选择:
- 不交易 vs 卖出并获得最大利润。
20行代码
profit = Math.max(profit, dp[i][j - 1] - prices[i])
profit代表在i天之前,选择某一天买入股票时,最大可能的潜在利润。dp[i][j-1]表示在第i天之前,最多允许j-1次交易时的最大利润。dp[i][j-1] - prices[i]表示如果在i天买入股票时的剩余利润:用dp[i][j-1]的值减去当天的价格prices[i],因为我们需要减去买入股票的成本。- 更新
profit的目的是为了在接下来的日子中找到最佳的买入点,以便后续卖出时能获得最大利润。