数据结构加速dp
在dp阶段增长过程中,当决策范围每次只扩大、不缩小时,那就可以仅用一个变量维护最值。
在复杂情况下,可以用到数据结构进行维护决策的候选集合。
例1:
用 $n$ 张贴纸覆盖一段长度为 $m$ 的丝带,每张丝带可以覆盖 $[L_i,R_i]$ ,价格为 $c_i$ ,求最小花费。
可以得到转移方程:
$$
dp[r_i]=\underset {l_i\leq x\leq r_i}{min}dp[x]+c_i
$$
$dp[x]$ 表示覆盖 $[1,x]$ 的最小花费。注意到此题本质即为求 $l_i\leq x\leq r_i$ 的最小值 $dp[x]$ ,那么可以用线段树维护最小值,每次查询即可。
例2:
给定长度为 $n$ 的数组,求有多少个严格递增子序列长度为 $m$ 。
可以得到转移方程:
$$
dp[i,j]=\sum_{k<j&&a_k<a_j}dp[i-1,k]
$$
$dp[i,j]$ 表示以 $a_j$ 结尾的长度为 $i$ 的子序列。普通dp需要三重循环,但是可以优化:
设 $val(x)$ 表示 $x$ 离散化之后的值,对每一个 $i$ ,在 $[1,N-1]$ 上建立树状数组;对于插入操作,执行 $add(val(a_k),dp[i-1,k])$ ,对于查询操作,执行 $dp[i,j]=ask(val(a_j)-1)$ 。
要尽量分离dp决策的限制条件,分离内外层循环,在内层循环时将外层循环看成定值。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Arn01d's planet!