算法随想Day43【动态规划】| LC121-买卖股票的最佳时机、LC122-买卖股票的最佳时机Ⅱ

LC121. 买卖股票的最佳时机

////自写的一般实现方法
int maxProfit(vector<int>& prices)
{
    int purchase = prices[0];
    int maxProfit = 0;
    int todayProfit = 0;
    for (int i = 1; i < prices.size(); ++i)
    {   
        todayProfit = prices[i] - purchase;
        if (todayProfit > maxProfit)
        {
            maxProfit = todayProfit;
        }
        if (prices[i] < purchase)
        {
            purchase = prices[i];
        }
    }    
    return maxProfit;
}

Carl哥动态规划分析:

  • dp[i] [0]含义:第 i 天持有股票的最大收益

    • 第 i - 1就持有股票,继续保持,不抛出没收益,dp[i] [0] = dp[i - 1] [0]
    • 第 i - 1不持有股票,第 i 天购入,dp[i] [0] = -price
  • dp[i] [1]含义:第 i 天不持有股票的最大收益

    • 第 i - 1就不持有股票,dp[i] [1] = dp[i - 1] [1]
    • 第 i - 1持有股票,第 i 天抛出,dp[i] [1] = dp[i - 1] [0] + price[i]

-price表示:买入了股票,但还没抛出,即还没有正收益,所以此时持有股票的收益为负数

  • dp数组初始化:

    • dp[0] [0] = -prices[0],先假设第一天购入
    • dp[0] [1]表示第0天不持有股票,不持有股票那么现金就是0,所以dp[0] [1] = 0
  • 举例子,如果有数组[7,6,4,3,1],那dp[i] [0]会每天被更新,从-7、-6 到 -1...。dp[i] [1]则会一直保持跟dp[0] [1]一致的“0”,因为根据dp[i] [1] = dp[i - 1] [0] + price[i],抛出股票时从未有正收益。

  • 在本题中不持有股票状态所得金钱一定比持有股票状态得到的多,所以最后返回dp[size - 1] [1]

int maxProfit(vector<int>& prices)
{
    int size = prices.size();
    vector<vector<int>> dp(size, vector<int>(2, 0));
    dp[0][0] = -prices[0];
    dp[0][1] = 0;
    for (int i = 1; i < size; ++i)
    {
        dp[i][0] = max(dp[i - 1][0], -prices[i]);
        dp[i][1] = max(dp[i - 1][0] + prices[i], dp[i - 1][1]);
    }
    return dp[size - 1][1];
}

LC122. 买卖股票的最佳时机Ⅱ

int maxProfit(vector<int>& prices)
{
    int size = prices.size();
    vector<int> dp(size);
    dp[0] = 0;
    for (int i = 1; i < size; ++i)
    {
        dp[i] = max(dp[i - 1] + prices[i] - prices[i - 1], dp[i - 1]);
    }
    return dp[size - 1];
}

虽然以简单的方式做出来了,但是Carl哥的方动规推导方式,还是要学习到和沿用:

在dp数组定义上依旧是采用

  • dp[i] [0]含义:第 i 天持有股票的最大收益

    • 第 i - 1就持有股票,继续保持,不抛出没收益,dp[i] [0] = dp[i - 1] [0]
    • 第 i - 1不持有股票,第 i 天购入,dp[i] [0] = -price
  • dp[i] [1]含义:第 i 天不持有股票的最大收益

    • 第 i - 1就不持有股票,dp[i] [1] = dp[i - 1] [1]
    • 第 i - 1持有股票,第 i 天抛出,dp[i] [1] = dp[i - 1] [0] + price[i]

区别是,在上一题中,因为股票全程只能买卖一次,所以如果买入股票,那么第i天持有股票即dp[i][0]一定就是 -prices[i]。而本题,因为一只股票可以买卖多次,所以当第 i 天买入股票的时候,所持有的现金可能有之前买卖过的利润。

int maxProfit(vector<int>& prices)
{
    int size = prices.size();
    vector<vector<int>> dp(size, vector<int>(2, 0));
    dp[0][0] = -prices[0];
    dp[0][1] = 0;
    for (int i = 1; i < size; ++i)
    {
        dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - prices[i]);
        dp[i][1] = max(dp[i - 1][1], dp[i - 1][0] + prices[i]);
    }
    return dp[size - 1][1];
}
posted @ 2023-03-15 13:31  冥紫将  阅读(40)  评论(0)    收藏  举报