参考
相关题目
- 121 买卖股票的最佳时机。限制了单次交易。dp[i][1]的第二项很有意思,因为最多允许交易1次,所以每次买完后,为了消除以前交易的影响,要将收益重置为-prices[i]。最多交易1次,和必须交易1次,是不同的。如果必须交易1次,用滚动数组的方法最好,但是利润需要初始化为-inf,因为必须交易1次可能会亏钱。
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
dp[i][1] = Math.max(dp[i - 1][1], -prices[i]);//第2项表示只允许交易1次。
- 122 买卖股票的最佳时机 II。不限制交易次数,状态转移方程最好写。
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]);
- 123 买卖股票的最佳时机 III 。这是188题k=2的特殊情况。
- 188 买卖股票的最佳时机 IV 。限制交易次数时,需要将交易次数也纳入状态定义中。k的遍历范围是1~K, k=0没有交易不用计算,就是初始状态。初始化时,先将所有状态置为-inf,表示非法状态。i=0时,如果没有操作,则dp[0][0][0]=0; 如果买入股票,则dp[0][1][1]=-p[0]。如果是用i=-1初始化,则dp[-1][0][0]=0,其它均为非法状态。这两种方法等价,满足状态转移方程。
dp[i][0][k] = Math.max(dp[i - 1][0][k], dp[i - 1][1][k] + prices[i])//卖出时交易次数不变
dp[i][1][k] = Math.max(dp[i - 1][1][k], dp[i - 1][0][k-1] - prices[i])//买入时交易次数加1
- 309 最佳买卖股票时机含冷冻期。
1.将冷冻期处理为第3种状态(前两种是持有、不持有),非常高明!如果冷冻期是N天,需要多定义N种状态,例如冷冻N、冷冻N-1等等,冷冻N只能来自持有状态,冷冻N可转换为冷冻N-1状态,冷冻1状态可转化为不持有状态。
2.在参考博文1中为了表示1天冷冻期,将状态方程的i-1改成了i-2,合理吗?
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 - 2][0] - prices[i])//i - 2表示1天冷冻期
合理!可以参考下图左边理解,图中画出了第i天的持有状态与i-1、i-2状态的关系。第1行是可行的,对应代码T[i - 2][0] - prices[i]。第2行不可行,因为i-1天卖的,需要等到i+1天才能买。第3、4行也是可行的,对应代码T[i - 1][1]。如果冷冻期是N天,就需要修改为T[i -1-N][0] - prices[i]。2天冷冻期的情况,可以参考下图右边理解,是正确合理的。
- 714 买卖股票的最佳时机含手续费 。只需在卖出时扣掉手续费。