我在做完洛谷的11月月赛后就去找了一些关于树形DP的题目,找到一道挺典型的叫Anniversart Party,是POJ的2342号题目,链接为
http://poj.org/problem?id=2342。废话不多说,直接上题解。
【题目大意】
某个公司要举办一场宴会,为了增强宴会的活跃度,每个人都不能在宴会中见到他的一个直接上司,已知每个人的活跃度和上司关系,问最多可得到的活跃度为多少?
【题意分析】
这一道题目因为每个人只有一个直接上司,则很显然是一棵树。题目的要求是选取若干个节点,使得这些节点互不为直接上司,且这些节点的活跃值最大。
【算法分析】
这就是一个树形DP。但是实际实现的时候,我觉得还是记忆化搜索更为方便。设f[root][0]为以root为根节点的子树中,不选root所能达到的最大的活跃值和。而f[root][1]则是相应的选root的最大活跃值和。那么下面来考虑一下如何转移。
f[root][0],代表着root不来,则root的下属可以来。则f[root][0]=sum(f[j][1])(j是root的直接下属或者说是直接孩子)。
f[root][1],代表着root来,则root的下属就不能够来。则f[root][1]=sum(f[j][0])
(j是root的直接下属或者说是直接孩子)
+root的活跃值。
最后的答案就是max{f[0][0],f[0][1]}。其中0是最高的上司。
【总结】
树形DP的最重要的一点就是将DP的节点列入DP方程之中,而且要意识到DP的那个图有相应的树形,这样才能够无后效性。所以说其实树形DP还是一个很简单的动态规划算法,但是只要能够准确地划分阶段就好了(不过其实一切的动态规划都应该是以划分状态为基础的……)。