树形dp
一些规律
-
状态转移方程
\(f[i][]\)表示\(i\)这棵子树怎样的最优解
-
用子树更新父亲
- 一个一个子树的更新父亲(树上背包)
- 计算完所有子树再更新子树
题型1:子树与计数
统计子树和,通过加减一些子树满足题目中的某些性质
-
Garland
统计以每个点为根的子树和,合并时遇到一个子树和为\(\frac{sum}{3}\)的节点就记录下来。
-
最大子树和
统计每个点的子树和,cut数组标记删除。统计的时候每个节点都统计一次。
题型2:树形背包问题
一般是让求在树上选一些点满足价值最大的问题
\(f[i][j]\)表示\(i\)这棵子树选\(j\)个点的最优解
-
选课
- 可能为一棵森林,添加\(0\)节点,使其变成一棵树。
- \(f[i][j]\)表示在\(i\)及其子树中选\(j\)门课的最大得分。
- 分组背包模型,对于一个节点\(x\),有$\left | son(x) \right | $ 组物品,每组物品有\(t-1\)个,第\(i\)组的第\(j\)个物品的体积为\(j\),价值为\(f[y_i][j]\),背包的总体积为\(t-1\)。
- code
-
有线电视网
- \(f[i][j]\)表示在\(i\)及其子树里满足\(j\)名用户的最大收益。
- 统计答案时逆序枚举\(i\),如果有\(f[1][i]\)大于等于\(0\),则输出\(i\)。
-
重建道路
题型3:花费最少的费用覆盖所有点
父亲与孩子有联系
1.选父亲必须不能选孩子(强制)
2.选父亲可以不用选孩子(不强制)
-
保安站岗
-
属于第二类
- \(1.\)用\(x\)这个点覆盖\(x\)
- \(2.\)用\(x\)的儿子节点\(y\)覆盖\(x\)
- \(3.\)用\(x\)的父亲节点\(fa\)覆盖\(x\)
-
分别用\(f[x][0],f[x][1],f[x][2]\)表示以\(x\)为根的子树中的所有点全部被覆盖,\(x\)的被覆盖状态分别上面的第\(1,2,3\)种状态。
-
\(f[x][0]+=min(f[y][0],f[y][1],f[y][2])+val[x]\)
\(x\)已经被自己覆盖了,\(y\)既可以被自己或自己的儿子覆盖,也可以被\(x\)覆盖。
-
\(f[x][1]+=min(f[y][0],f[y][1])\)
\(x\)已经被儿子节点覆盖了,\(y\)可以被自己或自己的儿子覆盖,但是不能被父亲覆盖。
当选择的全部是\(f[y][1]\)时,要加上\(min(f[y][0]-f[y][1])\)
\(x\)要被自己的儿子覆盖,但是\(x\)的所有儿子\(y\)都是被它的儿子所覆盖的,其实是没有儿子节点覆盖\(y\)的。此时要选一个最小的差值\(min(f[y][0]-f[y][1])\),强行使一个儿子节点选自己来覆盖\(x\)。
-
\(f[x][2]+=min(f[y][0],f[y][1])\)
\(x\)已经被父亲节点覆盖了,\(y\)可以被自己或自己的儿子覆盖,但是不能被父亲覆盖。
-
-
没有上司的舞会
-
树的最大独立集,属于第一类
-
\(f[i][0]\):在\(i\)这棵子树中,不选\(i\)的最大快乐指数。
\(f[x][0]+=max(f[y][1],f[y][0])\)
-
\(f[i][1]\):在\(i\)这棵子树中,选择\(i\)的最大快乐指数。
\(f[x][1]+=f[y][0]\)
-
-
Party at Hali-Bula
-
树的最大独立集+判断方案是否唯一
-
\(f[i][0/1]\):在\(i\)这棵子树中不选/选\(i\)的最大人数
\(g[i][0/1]\):在\(i\)这棵子树中不选/选\(i\)的方案是否唯一,\(g[x][0]\)为\(0\)表示方案唯一,为\(1\)表示不唯一。
-
\(f[x][1]+=f[y][0]\),\(g[x][1]|=g[y][0]\)
-
\(f[x][0]+=max(f[y][1],f[y][0])\)
-
\(f[y][1]==f[y][0]\) \(g[x][0]=1\)
已经有两种方案了。
-
\(f[y][1]>f[y][0]\) \(g[x][0]|=g[y][1]\)
-
\(f[y][0]>f[y][1]\) \(g[x][0]|=g[y][0]\)
-
-
题型4:树上统计方案问题
给一个条件,问有多少个点的集合满足这样的条件。
运用乘法原理,控制一个点不动,看它能做多少贡献
to be continued……
题型5:与其它算法结合&&大模拟
-
风铃
-
把题目中的要求变成公式。
-
\(mindep[i]\)表示\(i\)子树中最浅的玩具的深度
\(maxdep[i]\)表示\(i\)子树中最深的玩具和深度
\(dep[i]\)表示节点\(i\)的深度
-
\(f[i]\)表示\(i\)这棵子树中构成满足条件的玩具所需的操作数。
加边时,先添加右边的玩具后添加左边的玩具,这样遍历到一个节点时,一定会先遍历右边的玩具后便利左边的玩具。
合并时,\(f[x]=f[toy[1]]+f[toy[2]]+((mindep[toy[1]]<maxdep[toy[2]])?1:0)\)。
-
\(n\)是杆的数量,不是玩具的数量……多开几倍空间
-
to be continued……
-
参考: [树形dp+树形结构总结](

浙公网安备 33010602011771号