P3446【HN Training 2015 Round7】
问题描述
容易发现最后答案是树上的一个联通块,但直接dp难度较大,考虑用点分治转化成一定包含根的联通块。
点分治后,每一层考虑包含根的联通块,那么转化成一个树形依赖背包,只有选了父节点才能选子节点,并且每个物品有个数限制。
这里对于这种树形依赖dp,可以采用dfs序来简化,因为在dfs序中,一颗子树必然是连续的一段,那么令$F[i][j]$表示在$dfs序i-n这些节点中容积为j的背包的最优解$,因此在物品数量均为1时可以得到dp方程
$$
F[i][j]=max(F[i+size[i]][j],F[i+1][j-c[i]]+w[i])
$$
第一个转移表示不选i节点的物品,那么跳过i这颗子树,第二个转移表示选。答案就是$F[1][m]$
接着考虑物品数量的限制,这里我用的二进制拆分的方法,即将d个物品拆成$log\ d$个物品,举个例子,比如将$10$个物品可以拆成$1,2,4,3$这4个物品,容易发现,无论从这10个物品中取多少个,都可以用上述4个物品表示出来。
修改后的dp方程可以参照代码,改动不大,只是多了一个$log$的复杂度。最终复杂度$Tnm\log n\log d$,实际上跑得还是很快。
代码:
1 |
|