动态规划的学习—从暴力递归到动态规划
发布日期:2021-05-07 16:07:34 浏览次数:17 分类:精选文章

本文共 2118 字,大约阅读时间需要 7 分钟。

lc343 | 买股票问题

在这里,我们将从暴力递归开始,然后逐步改写为动态规划。

暴力递归思路

我们可以采用递归的方法来解决这个问题。假设我们有一个数组 prices,记录股票的价格。每一天,我们可以选择买入、卖出或者不买入股票。递归函数 dfs 可以接受当前的索引 index 和一个布尔 flag,表示是否已经买入股票。

递归函数的逻辑如下:

  • 如果 index 超过了数组的长度,说明交易结束,返回0利润。
  • 如果已经买入(flagtrue),那么只能卖出,计算利润,然后递归。
  • 如果没有买入(flagfalse),则有三种选择:
    • 继续观望,不买入,递归 index + 1flag 不变。
    • 买入,记录利润,然后递归 index + 1flag 变为 true
    • 卖出,计算利润,然后递归 index + 1flag 变为 false
  • 为了优化递归,我们需要使用记忆化来缓存已经计算过的状态。

    动态规划思路

    既然我们已经写出了递归函数,我们可以将递归的状态转换为动态规划的状态转移方程。我们可以使用一个二维数组 dp,其中 dp[i][j] 表示到第 i 个交易日,处于状态 jj = 0 表示没买,j = 1 表示买)的最大利润。

    • 初始化:dp[n][0] = 0dp[n][1] = -prices[n-1](这里 n 是数组的长度)。
    • n-1 往回推,计算每一天的最大利润:
      • 对于每一天 i
        • 如果当前状态是没买(j=0),那么最大利润可以是买入后卖出的利润加上后续的最大利润,或者不买入,继续后续的最大利润。
        • 如果当前状态是买入(j=1),那么只能卖出,得到利润,加上后续的最大利润。

    代码

    递归代码:

    #include 
    using namespace std;class Solution { int dfs(const vector
    & prices, int index, bool flag) { if (index >= prices.size()) return 0; if (flag) { return 0 - prices[index] + dfs(prices, index + 1, false); } else { int buy = 0 - prices[index] + dfs(prices, index + 1, true); int not_buy = dfs(prices, index + 1, false); return max(buy, not_buy); } }public: int maxProfit(vector
    prices) { return dfs(prices, 0, true); }};

    动态规划代码:

    class Solution {public:    int maxProfit(vector
    prices) { int n = prices.size(); vector
    > dp(n + 1, vector
    (2, 0)); dp[n][0] = 0; dp[n][1] = -prices[n - 1]; for (int i = n - 1; i >= 0; --i) { for (int j = 0; j < 2; ++j) { dp[i][j] = dp[i + 1][j]; if (j == 0) { dp[i][j] = max(dp[i][j], dp[i + 1][1] + prices[i]); } else { dp[i][j] = max(dp[i][j], dp[i + 1][0] - prices[i]); } } } return dp[0][1]; }};

    代码说明

  • 递归代码

    • dfs 函数接受当前索引和是否已经买入的状态。
    • 如果已经买入(flagtrue),则卖出,计算利润,并递归下一天。
    • 如果没有买入(flagfalse),则有三种选择:买入、卖出或不买入,返回最大利润。
  • 动态规划代码

    • 使用二维数组 dp,记录每一天的最大利润。
    • 从最后一天开始,向前填充 dp 表。
    • 状态转移方程根据递归的逻辑进行填充,最终返回 dp[0][1],即最大的利润。
  • 上一篇:初识valgrind,valgrind内存泄漏分析
    下一篇:最近一些算法题的总结

    发表评论

    最新留言

    关注你微信了!
    [***.104.42.241]2025年04月10日 13时54分04秒