1.7学习博客

今天继续训练了三道dp题目
第一题:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee/
在这里插入图片描述
根据官方题解思想,每天交易结束后只可能存在手里有一支股票或者没有股票的状态。
定义状态 dp[i][0] 表示第 i天交易完后手里没有股票的最大利润,dp[i][1] 表示第 i天交易完后手里持有一支股票的最大利润(i 从 0 开始)。

考虑 dp[i][0] 的转移方程,如果这一天交易完后手里没有股票,那么可能的转移状态为前一天已经没有股票,即 dp[i−1][0],或者前一天结束的时候手里持有一支股票,即 dp[i−1][1],这时候我们要将其卖出,并获得 prices[i] 的收益,但需要支付 fee 的手续费。因此为了收益最大化,我们列出如下的转移方程:
dp[i][0]=max(dp[i-1][0],dp[i-1][1]+prices[i]-fee);
再来按照同样的方式考虑 dp[i][1] 按状态转移,那么可能的转移状态为前一天已经持有一支股票,即dp[i−1][1],或者前一天结束时还没有股票,即 dp[i−1][0],这时候我们要将其买入,并减少 prices[i] 的收益。可以列出如下的转移方程:
dp[i][1]=max(dp[i-1][1],dp[i-1][0]-prices[i]);
对于初始状态,根据状态定义我们可以知道第 0 天交易结束的时候有dp[0][0]=0 以及 dp[0][1]=−prices[0]。

因此,只要从前往后依次计算状态即可。由于全部交易结束后,持有股票的收益一定低于不持有股票的收益,因此这时候 dp[n−1][0] 的收益必然是大于dp[n−1][1] 的,最后的答案即为 dp[n−1][0]。
部分代码:
在这里插入图片描述
第二题:https://leetcode-cn.com/problems/unique-binary-search-trees/
在这里插入图片描述
官方题解用dp的思路描述的非常清晰啊
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
部分代码:
在这里插入图片描述
第三题:https://leetcode-cn.com/problems/minimum-path-sum/

在这里插入图片描述
在这里插入图片描述
由于路径的方向只能是向下或向右,因此网格的第一行的每个元素只能从左上角元素开始向右移动到达,网格的第一列的每个元素只能从左上角元素开始向下移动到达,此时的路径是唯一的,因此每个元素对应的最小路径和即为对应的路径上的数字总和。

对于不在第一行和第一列的元素,可以从其上方相邻元素向下移动一步到达,或者从其左方相邻元素向右移动一步到达,元素对应的最小路径和等于其上方相邻元素与其左方相邻元素两者对应的最小路径和中的最小值加上当前元素的值。由于每个元素对应的最小路径和与其相邻元素对应的最小路径和有关,因此可以使用动态规划求解。

创建二维数组 dp,与原始网格的大小相同,dp[i][j] 表示从左上角出发到 (i,j) 位置的最小路径和。显然,dp[0][0]=grid[0][0]。对于 dp 中的其余元素,通过以下状态转移方程计算元素值。
当 i>0 且 j=0 时,dp[i][0]=dp[i−1][0]+grid[i][0]。

当 i=0 且 j>0 时,dp[0][j]=dp[0][j−1]+grid[0][j]。

当 i>0且 j>0 时,dp[i][j]=min(dp[i−1][j],dp[i][j−1])+grid[i][j]。

最后得到dp[m−1][n−1] 的值即为从网格左上角到网格右下角的最小路径和。

部分代码:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_47529865/article/details/112328809
1.7