前言
此文章的作用:教会读者用简单、快速、稳定的方法推出线性DP的转移方程。
笔者希望通过一些题教会读者做所有线性DP的方法,而不是只教会读者这些题的解法。
先看题:一本通 大盗阿福
我们发现:店铺越多,可以偷的店铺就越多,能得到的现金就越多。
举例:如果只有一家店铺,你就只能偷第一家,只能拿到第一家店铺的现金。但如果有三家店铺,你就可以偷第一和第三家,同时拿到第一家和第三家的现金。
这说明:(最多可以得到的现金)是(店铺数量)的函数
这又说明表示状态中肯定有一个维度是店铺数量。
所以暂时设 d p i dp_i dpi :偷前 i i i 家店铺的最大值。
再次观察发现对于每个店铺只有偷和不偷两个选择。
所以设 d p i , [ 0 / 1 ] dp_{i,[0/1]} dpi,[0/1]:对于前 i i i 家店铺, [ [ [ 不偷 ( 0 ) (0) (0) / / / 偷 ( 0 ) (0) (0) ] ] ] 第 i i i 家店铺的最大值。
有了状态,就要推状态转移方程了。
第一种画法
回归标题,我们用带权的有向图描述状态的转移,其中点表示状态,边表示状态的转移增量
先画出有哪些状态,如图:
先考虑 d p i , 0 dp_{i,0} dpi,0 可以由那些状态转移过来
- d p i , 0 dp_{i,0} dpi,0 是否可以由 d p i − 1 , 0 dp_{i-1,0} dpi−1,0 转移过来?两家店铺都没有偷,不会触发警报,可以转移。因为并当前状态没有选择偷第 i i i 个店铺,所以转移增量为 0 0 0 。所以,有一条边权为 0 0 0 的边从 d p i − 1 , 0 dp_{i-1,0} dpi−1,0 连向 d p i , 0 dp_{i,0} dpi,0(边权为 0 0 0 的默认不在图上标出边权)。
现在的图就变成了这样:
- d p i , 0 dp_{i,0} dpi,0 是否可以由 d p i − 1 , 1 dp_{i-1,1} dpi−1,1 转移过来?只偷上一家店铺,不偷当前店铺,没有同时偷相邻的两家,不会触发警报,所以可以转移。同样因为并当前状态没有选择偷第 i i i 个店铺,所以转移增量为 0 0 0 。所以,有一条边权为 0 0 0 的边从 d p i − 1 , 0 dp_{i-1,0} dpi−1,0 连向 d p i , 0 dp_{i,0} dpi,0(边权为 0 0 0 的默认不在图上标出边权)。
现在的图就变成了这样:
现在考虑 d p i , 1 dp_{i,1} dpi,1 可以由哪些状态转移过来
- d p i , 1 dp_{i,1} dpi,1 是否可以由 d p i − 1 , 0 dp_{i-1,0} dpi−1,0 转移过来?只偷当前店铺,不偷上一家店铺,没有同时偷相邻的两家,不会触发警报,所以可以转移,因为并当前状态选择偷第 i i i 个店铺,所以转移增量为 w i w_i wi ,所以,有一条边权为 w i w_i wi 的边从 d p i − 1 , 0 dp_{i-1,0} dpi−1,0 连向 d p i , 0 dp_{i,0} dpi,0。
现在的图就变成了这样:
- d p i , 1 dp_{i,1} dpi,1 是否可以由 d p i − 1 , 1 dp_{i-1,1} dpi−1,1 转移过来?即偷了上一家店铺,也偷了当前店铺,同时偷了相邻的两家,会触发警报,所以不能转移。
第二种画法
这道题对于每个店铺都有 [ [ [ 不偷 ( 0 ) (0) (0) / / / 偷 ( 1 ) (1) (1) ] ] ] 两种状态,如图:
- 状态 0 0 0 可以由状态 0 0 0 转移过来,转移增量为 0 0 0。
- 状态 0 0 0 可以由状态 1 1 1 转移过来,转移增量为 0 0 0。
- 状态 1 1 1 可以由状态 0 0 0 转移过来,转移增量为 w i w_i wi。
- 状态 1 1 1 不可以由状态 1 1 1 转移过来。
那么,看着图就很容易写出状态转移方程了。
d p i , 0 = max ( d p i − 1 , 0 , d p i − 1 , 1 ) dp_{i,0}=\max(dp_{i-1,0},dp_{i-1,1}) dpi,0=max(dpi−1,0,dpi−1,1)
d p i , 1 = d p i − 1 , 0 dp_{i,1}=dp_{i-1,0} d