【专题】树形动态规划

AIDreamer

2017/5/30

树形DP就是状态之间的关系是树状结构的DP

树

【例题一】poj 2342 Anniversary party

题目大意

有一群人,每个人有一个欢乐值,这些人之间存在着一些上司和下属关系如A是B的上司,现在让你选出一些人满足这些人之间不存在直接的上司和下属关系并且使得总的欢乐值最大,问最大的欢乐值是多少。

分析

这种关系画出来是成树形的,节点代表一个人,节点上有一个值表示这个人的欢乐值,每个节点有两种状态:选或不选。这样我们的问题就转化成了:

在一颗点权树上选择一些节点满足任意两个节点不相邻使得被选节点的总权值最大并输出最大权值

我们可以通过观察发现:

1.如果某个节点不选,那么这个节点以下的分支可以单独作为一个新问题来求解

2.如果某个节点被选,那么这个节点的儿子一定不会选,那么这个节点的儿子们的分支可以作为一个新的问题来求解

这样就把问题不断地缩小直到能直接求解为止。

我们用 dp[i][1] dp[i][0] 分别表示节点i不选和不选的情况下以节点i为根的树得到的最大值

那么有

{dp[i][1]=jidp[j][0]dp[i][0]=jimax{dp[j][0],dp[j][1]}

实现方式

正如一般的动态规划问题基本上都可以分为两种实现方式:自上而下的递归实现自下而上的非递归实现

而对于树形DP如果用自下而上的实现方式通常需要结合拓扑排序比较麻烦,所以更常用递归的方式从根节点出发自上而下递归求解。

树形DP比较像动态规划思想与分治思想的结合,状态的转移其实就是一个分治的过程,将对原问题的求解分解(某个节点的状态)为对若干相互独立且与原问题性质相同的子问题的求解(该节点的分支)

【例题二】POJ 1935 Journey

题目大意

给你一棵边权树,要访问树上的m个节点,并且最后不用返回根,所走的最短距离是多少

分析

先从一个类似的但更为简单的问题出发开始分析。

如果问题的要求是最后需要返回根节点,我们通过几次手动模拟之后就会发现,不管怎么走,所走的距离是个定值:所有边权和*2

而现在告诉我们最后不用返回根,那么最短距离= 2max{}

所以我们的问题就转化成了找距根节点最远的节点的距离。

令dp[i]表示节点i距离该分支下最远的被选中节点的距离,那么我们可以很容易得到状态的转移方程:

dp[i]=maxji{dp[j]+w[i][j]},w[i][j]ij

整个动态规划的过程就是一个搜索的过程,由于是问题的结构是树状的,所以甚至可以省去了记忆化搜索中记忆化的操作。

【例题三】POJ 1947 Rebuilding Roads

题目大意:

一颗含有n个结点的树,减去最少的边使得该树只含有p个结点,问最少的边的数量是多少。

分析:

拆点

我们令 dp[s][i] 表示以第s个节点为根,保留i个节点所需减去的最少的边。

有了状态之后接下来就该考虑怎么进行状态的转移。

考虑其儿子k
1)如果不去掉k子树,则

dp[s][i]=min{dp[s][j]+dp[k][ij]},0<=j<=i

2)如果去掉k子树,则
dp[s][i]=dp[s][i]+1

总的为
dp[s][i]=min{min(dp[s][j]+dp[k][ij]),dp[s][i]+1}

总结:

这道题可以看成是树形DP和背包的结合,整个问题的状态是在一个树形的结构上进行转移的,而对于每一次状态转移我们相当于是做了一次背包。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值