0%

DP(四)

状态机 DP

笔者其实更愿意称之为“分类DP”。

状态机本身概念与算法无关,选择性理解。

解释:包含多个待选状态,不同的状态之间有相互转化的方法,我们可以借助这些转化的手段,达成状态之间的相互转移。

例 $1$:

给定一支股票 $n$ 天的价格 $a_i$,最多持有一只股票,买入卖出共视作一次交易,最多进行 $k$ 次交易,求最大收益。

买入/卖出是通过卖出/买入的状态转移来的,而不是通过更小规模的相同结构转移过来,称这样的 DP 过程为状态机 DP。

状态:

设 dp$[i][j][0/1]$ 表示到第 $i$ 天,共进行 $j$ 次交易,且第 $i$ 天为买入/卖出的最大收益。

转移:

$(i,j,0)\leftarrow(i-1,j-1,1),(i-1,j,0)$

$(i,j,1)\leftarrow(i-1,j,0),(i-1,j,1)$

DP 式子:

For(i,1,n) For(j,1,k) dp[i][j][0]=max(dp[i-1][j][0],dp[i-1][j-1][1]-a[i]),dp[i][j][1]=max(dp[i-1][j][1],dp[i-1][j][0]+a[i])

空间上显然可以滚动数组优化。

时间复杂度:$O(nk)$。

空间复杂度:$O(k)$。

例 2:

给定一支股票 $n$ 天的价格 $a_i$,最多持有一只股票,买入卖出共视作一次交易,卖出股票后第二天不能买入,求最大收益。

状态:

设 dp$[i][j][0/1/2]$ 表示到第 $i$ 天,共进行 $j$ 次交易,且第 $i$ 天为买入/卖出/不操作的最大收益。

转移:

$(i,0)\leftarrow(i-1,0),(i-1,2)$

$(i,1)\leftarrow(i-1,0)$

$(i,2)\leftarrow(i-1,2),(i-1,1),(i-1,0)$

DP 式子:

For(i,1,n) dp[i][0]=max(dp[i-1][0],dp[i-1][2]-a[i]),dp[i][1]=dp[i-1][0]+a[i],dp[i][2]=max(dp[i-1][2],max(dp[i-1][0],dp[i-1][1]))

同样地容易得出可以滚动数组优化空间。

时间复杂度:$O(n)$。

空间复杂度:$O(1)$。