本题的模型是树形状态压缩的动态规划。
首先考虑简单的题目模型:对于任何形态的有根树 T,都可以建立其等效二叉树 T’,若在原树 T 中,结点 x 有儿子
c1,c2,c3,…,ck
,则在二叉树中,与之对应的结点 x’有儿子
c1和h1,h1有儿子c2和h2,
以此类推,
hk−2有儿子ck−1和ck。
并且所有 hi 都不能建立分部。其他的树的结点的权均有一一对应关系。容易知道在 T 中的最优规划等效于在 T’中的最优规划。
对于二叉树,设计状态 f[n][s]表示以第 n 个结点为根的子数中安排集合 s 的山贼集团分部的最优获利。状态 g[n][s]表示以第 n 个结点为子数不考虑根的安放情况下,安排集合s 的山贼集团分部的最优获利。
易知
g[n][s]=maxf[cl][p]+f[cr][s−p]
,其中 cl,cr 为 n 的两个子数,p 为s 的某个子集。
且
f[n][s]=maxg[n][p]+cost[n][s−p]+value[s]
, 其中 p 为 s 的子集,
cost[n][s]
表示在结点 n 修建集合 s 的分部所获得的收益, value[s], 表示某个结点相对于集合 s 的收益。
关于上述算法, 最直接的实现是首先使用多叉树转二叉树, 然后直接套用上述递推公式进行计算。其次也可以不转二叉树,而在每个结点的转移处使用嵌套递推的方法。两种方法各有好处,在标程的实现中由于作者习惯采用了二次递推的方法。
在转移处需要枚举某个集合的所有子集, 如果使用直接枚举所有集合然后判断他是不是给定集合的子集,那么复杂度将会是
O(n∗4p)
,面临超时的危险,下面我们将看到,如果首先预处理出所有集合的子集是哪些的情况下,复杂度将会下降为
O(n∗3p)。