DP小结

DP小结

DP本质就是状态压缩——只记录和答案有关的值。

所以DP的解法大概就是:

①不断探索问题性质(数位DP体现得比较明显,如BZOJ1026 windy数,还有一道缺了题号的题

②减少那些和答案有关的值的个数(比如要从题目中筛选信息来定出状态,列出方程)。

——scαpe

只是说说而已,DP并没有什么定式。

一些方法

这些方法说不定可以提供一些思路[滑稽]。

以下内容完全按照意识流顺序出现。

刷表法与填表法

举个例子来说,就是:

刷表法(也经常在状态压缩里面遇见,也许可以避免初始化):当简单的状态不方便表示的时候,可以考虑刷表法,比如 f [ i + k ] + = f [ i ] 之类的。如 f [ i ] [ j ] = ( @ ! . / ) f [ i 1 ] [ j 1 ] 之类的神仙转移就可以用刷表法。比如一道缺了题号的题

填表法: f [ i ] = f [ i 1 ] . . . 之类。

分解步骤

把一个大的东西分成很多个小块讨论。比如计算一堆链的权值和,一条链由很多线段构成,可以把每条线段对答案的贡献单独提出来算(BZOJ4033 树上染色);比如求一堆数字的二进制位的 x o r , o r , a n d . . . 值,可以按位运算,即把这一堆数的某一位提出来单独运算,最后把答案合起来……

单独计算枚举上限

防止时间复杂度退化。具体看题目咯,比如BZOJ4033 树上染色

树形DP常用状态

状态中有一维表示以 i 为根的子树。比如BZOJ4033 树上染色中的状态 f [ i ] [ j ] 表示 i 为根的子树中有 j 个黑点。

两两合并子问题(树形DP)

一棵树可以有很多儿子,这些儿子又有很多新儿子……(无限递归调用)设 i 为树的根,它的 n 个儿子分别为 s 1 , s 2 , s 3 , . . . , s n 。那么按顺序以如下方式计算:

s 1 + s 2 ; s 1 , s 2 + s 3 ; s 1 , s 2 , s 3 + s 4 ; . . . ; s 1 , s 2 , s 3 . . . s n 1 + s n

+号左边的部分看做一个整体,右边看做另一个整体,依次合并。最后一次合并之后就得到了以 i 为根的树的相关值。比如BZOJ4033 树上染色

前缀思想(数位DP)

[ a , b ] 中满足某一特征的数,可看为 [ 1 , b ] [ 1 , a 1 ] 两步。

例如:BZOJ1026 windy数 BZOJ1799 self 同类分布

嵌套DP

一些DP题,一次DP不够,还要在第一次DP的基础上再来一波DP。

比如BZOJ2287 消失之物退背包问题

一篇树形DP的总结
……

暂时就这些了吧?竟然哔哔了这么多,汗

猜你喜欢

转载自blog.csdn.net/ArliaStark/article/details/81329177
今日推荐