买卖股票的最佳时机II

继续每日一题,今天给大家分享一道经典的多维动态规划题目:买卖股票的最佳时机II

题目描述:

给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。

在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。

返回 你能获得的 最大 利润 。

题目示例:
在这里插入图片描述

对于动态规划类的题目,无论是一维还是多维,我们的目的都是找到一个合适的状态转移方程来满足无后效性,对于本题,我们除了要标记收益之外还需要知道当前收益下的持股状态,所以我们声明dp数组:dp[i][j],表示:

下标为 i 的这一天,持股状态为 j 时,我们手上拥有的最大现金数。

j有两种状态:股票(1) or 现金(0)

  • dp[i][0]:表示在第i天持有现金的最大收益
  • dp[i][1]:表示第i天持有股票的最大收益

所以我们的公式如下;
dp[i][j]={Math.max(dp[i−1][0],dp[i−1][1]+price[i]), j==0 Math.max(dp[i−1][1],dp[i−1][0]−price[i]), j==1  dp[i][j]= \begin{cases} Math.max(dp[i-1][0],dp[i-1][1]+price[i]), & \text{ $j==0$ } \\ Math.max(dp[i-1][1],dp[i-1][0]-price[i]), & \text{ $j==1$ } \end{cases} dp[i][j]={Math.max(dp[i1][0],dp[i1][1]+price[i]),Math.max(dp[i1][1],dp[i1][0]price[i]), j== j==
我来给大家解释一下每状态下的公式含义

  • dp[i][0]即当天持有的是现金的情况,这种情况需要我们在当天卖出股票换成钱

如果前一天持有的也是现金即dp[i-1][0],那么当天就无可卖出的股票,所以收益和前一天是一样的

如果前一天持有的是股票即dp[i-1][1],那么当天就有可卖出的股票,卖出的钱就是price[i],所以当天的收益为:p[i-1][1]+price[i]

  • dp[i][1]即当天持有的是股票的情况,这种情况需要我们买入股票

如果前一天持有的是股票即dp[i-1][1],因为题目要求无论在任何时候都只能有一支股票,所以当天就无法买入,收益和前一天一样

如果前一天持有的是现金即dp[i-1][0],那么当天就有可以买入股票,买入的价格则是price[i],此时我们的收益就需要减去买股票的钱,即:p[i-1][0]-price[i]

了解上面内容后,我们还有最后一点待定,就是初始值,在动态规划的题目中,我们的步骤就是确定动态转移方程以满足无后效性问题,第二步则是确定初始值

  • dp[0][0],第一天持有现金,则无任何收益,故:dp[0][0]=0;
  • dp[0][1],第一天持有股票,则需要买入,买入的价格为:price[0],故:dp[0][1]=0-price[0]

代码实现(java):

     public int maxProfit(int[] prices) {
        int n = prices.length;
        int[][] dp = new int[n][2];
        //0:持有现金 1:持有股票
        dp[0][0] = 0;
        dp[0][1] = 0 - prices[0];
        for (int i = 1; i < n; 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 - 1][0] - prices[i]);
        }
        //找最大收益
        return Math.max(dp[n - 1][0], dp[n - 1][1]);
    }
考虑可再生能源出力不确定性的商业园区用户需求响应策略(Matlab代码实现)内容概要:本文围绕“考虑可再生能源出力不确定性的商业园区用户需求响应策略”展开,结合Matlab代码实现,研究在可再生能源(如风电、光伏)出力具有不确定性的背景下,商业园区如何制定有效的需求响应策略以优化能源调度和提升系统经济性。文中可能涉及不确定性建模(如场景生成与缩减)、优化模型构建(如随机规划、鲁棒优化)以及需求响应机制设计(如价格型、激励型),并通过Matlab仿真验证所提策略的有效性。此外,文档还列举了大量相关的电力系统、综合能源系统优化调度案例与代码资源,涵盖微电网调度、储能配置、负荷预测等多个方向,形成一个完整的科研支持体系。; 适合人群:具备一定电力系统、优化理论和Matlab编程基础的研究生、科研人员及从事能源系统规划与运行的工程技术人员。; 使用场景及目标:①学习如何建模可再生能源的不确定性并应用于需求响应优化;②掌握使用Matlab进行商业园区能源系统仿真与优化调度的方法;③复现论文结果或开展相关课题研究,提升科研效率与创新能力。; 阅读建议:建议结合文中提供的Matlab代码实例,逐步理解模型构建与求解过程,重点关注不确定性处理方法与需求响应机制的设计逻辑,同时可参考文档中列出的其他资源进行扩展学习与交叉验证。
### 解题思路 LeetCode 122 题要求通过股票交易获得最大利润,允许进行多次交易(即在买入并卖出股票后,可以再次买入并卖出)。问题的核心在于如何选择买入和卖出的时机,以最大化总利润。 #### 贪心算法 贪心算法是解决该问题的高效方法。其核心思想是:只要第二天的价格高于今天,就进行交易,将差值计入总利润。这样可以保证每次交易都获得正收益,最终实现全局利润的最大化[^4]。 这种方法的时间复杂度为 $O(n)$,其中 $n$ 是价格数组的长度。空间复杂度为 $O(1)$,因为只需要常数级别的额外空间。 #### 示例说明 以 `prices = [7,1,5,3,6,4]` 为例: - 在第 2 天买入(价格为 1),第 3 天卖出(价格为 5),利润为 4。 - 在第 4 天买入(价格为 3),第 5 天卖出(价格为 6),利润为 3。 - 总利润为 7。 通过贪心策略,可以在每一天比较是否值得买入或卖出,从而逐步累积最大利润[^2]。 ### 代码实现 以下是基于贪心算法的实现: ```cpp class Solution { public: int maxProfit(vector<int>& prices) { int ans = 0; for (int i = 0; i < prices.size() - 1; ++i) { // 如果第二天价格高于当天,则交易 if (prices[i + 1] > prices[i]) { ans += prices[i + 1] - prices[i]; } } return ans; } }; ``` ### 改进版实现 另一种改进版本使用了更复杂的逻辑来处理买入和卖出的状态管理,适用于某些特殊情况下的优化需求: ```c int maxProfit(int* prices, int pricesSize) { int buy = -1, sell = 0, sum = 0, i = 0; while (i < pricesSize) { if (buy == -1) { if (i + 1 < pricesSize && prices[i] < prices[i + 1]) { buy = prices[i]; sell = prices[i + 1]; } } else { if (i + 1 >= pricesSize || prices[i] > prices[i + 1]) { sum += sell - buy; buy = -1; } else { sell = prices[i + 1]; } } i++; } return sum; } ``` 该实现通过状态变量 `buy` 和 `sell` 来跟踪当前是否持有股票,并根据价格趋势决定是否继续持有或卖出[^3]。 ### 算法特点 - **时间效率**:由于仅遍历一次价格数组,时间复杂度为线性级别。 - **空间效率**:不需要额外存储数据结构,空间复杂度为常数级别。 - **适用场景**:适用于允许多次交易且不禁止连续买卖的情况。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZNineSun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值