首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往
您找到你想要的搜索结果了吗?
是的
没有找到

【树形 DP】树形 DP 的通用思路

Tag : 「树形 DP」、「DFS」、「动态规划」 树是一个无向图,其中任何两个顶点只通过一条路径连接。换句话说,一个任何没有简单环路的连通图都是一棵树。...可选择树任何一个节点作为根。当选择节点 x 作为根节点时,设结果树的高度为 h 。在所有可能的树,具有最小高度的树(即,min(h))被称为 最小高度树 。...= bi 所有 (ai, bi) 互不相同 给定的输入保证是一棵树,并且不会有重复的边 树形 DP 这是一道树形 DP 模板题。...即树的形态如图所示(一些可能有的出边用虚线表示): 树形 DP 问题通常将问题根据「方向」进行划分。...假设我们可以通过 DFS 预处理出 f 数组和 g 数组: f[u] 代表在以 0 号点为根节点的树,以 u 节点为子树根节点时,往下的最大高度 g[u] 代表在以 0 号点为根节点的树

27920

插头DP小结_dp插头接线标准

插头DP一般都是棋盘模型,找路径或者环路最值或者方案数。 插头:说白了就是两个联通的格子,一个走向另一个,那么这里就有一个插头。...轮廓线:DP逐格DP,那么轮廓线可以分开DP过的格子和未DP的格子。轮廓线的长度明显是m+1。插头垂直于轮廓线。 转移: 轮廓线在换行的时候要位移,这个画画图就出来了。...那么插头就有3种,一种是没插头,一种是插头从已DP的指向未DP的,一种是未DP的指向已DP的。 具体实现,有两种思路,一种是括号序列,一种是最小表示法。...写法有三种,一种是hash表存取状态,有decode,encode,就是kuangbin那种写法;一种是传统dp写法,位运算取出状态;还有种是claris写法,预处理所有可能状态然后传统DP转移。...因为括号序列的性质,轮廓线上m+1个点最多只有m/2个不同的联通块,根据这个压位DP。 如果左插头和上插头都有,那么右插头和下插头就没有了。

79430

树形DP

树形dp就是在树上进行的dp。由于树具有递归的性质,因此树形dp一半都是用递归的方式进行的。 问题的大意是,选了父节点,那么它的直接子节点就不能被选择,求总的权值的最大值。...题目:P1352 没有上司的舞会 这题是树形dp的板子题,每个节点都有被选择和不被选择两种情况。 用数组dp[n][0]记录第n个节点不被选择的情况,用数组dp[n][1]记录被选择的情况。...那么就有状态转移方程 dp[n][0] = Σ(max(dp[x][0],dp[x][1]),其中,x是n的所有子节点 dp[n][1] = a[n] + Σ(dp[x][0]) 然后总的权值和的最大值就是...max(dp[root][0],dp[root][1]) 下面给出代码实现: #include using namespace std; #define MAXN 6006...[u][0] += max(dp[e[i].v][0], dp[e[i].v][1]); dp[u][1] += dp[e[i].v][0]; } } bool is_root

1.1K30

树形DP

从五道题来看树形DP 1.求树的最大值和最小值  假设现在有一棵树,我只要求出每个结点作为头节点对应子树的最大值和最小值,那么最终答案一定在其中,因此每个结点都有两个信息,最大值和最小值,我把这个信息封装为一个结构体...因此结构体存的信息应该有最大值、最小值、头节点以及大小 public class Main { class Data { int max,min,size;...Math.max(Math.max(leftMax,rightMax),head.value)); } } 3.求一棵二叉树上的最远距离  二叉树,...对于一个结点来说,最大距离可能分为两种情况,经过我这个结点和不经过我这个结点,不经过我这个结点又分为两种情况:左子树的最大距离和右子树的最大距离较大的那个。...本身也就用到递归的思想,树形DP难在将所有的信息考虑全,普通的DP难在递归方程式怎么写

1.4K40

Dp练习

//从这里我们就可以知道 dp[i][j] : 表示 在第 i 行, 第 j 列 ,我们可以得到的最大的和为 dp[i][j] 以上就是我推断出的dp数组的含义 接下来就是dp的初始化 //1. dp[...; } //因为如果我们只对dp[0][0] 进行初始化的话, 那么后序 的dp[2][2] 就需要dp[1][1] 和 dp[1][0];但是我们的dp[1][0] //确是只能由dp[0][0]得出...同时dp[1][1] 也是只能由dp[0][0] 得出 //所以我们需要将dp[i][0]也进行初始化 通过 dp[i][0] = arr[i][0] + dp[i-1][0]; 这样我们得到的dp[...接下来就是dp的公式 //因为我们之前推出的公式我们得到了dp[i][0] 的数据 //所以接下来就可以按照题意将其余的dp[i][j] 推出 dp[i][j] = arr[i][j] + Math.max...最终的结果一定是在其中间 所以进行判断一下即可 实现 import java.util.Scanner; // 1:无需package // 2: 类名必须Main, 不可修改 public class

8810

DP:两个数组的dp问题

(LeetCode) 算法原理: 1、状态表示(经验+题目要求) dp[i][j]表示:s1的[0,i]区间以及s2的[0,j]区间内的所有子序列,最长公共子序列的长度。...(string s, string p) { //两个数组的dp问题 //p0-j的子串能否匹配s0-i的子串 int m=s.size(),n=p.size...{ public: bool isMatch(string s, string p) { //p0-j的子串能否匹配s0-i的子串 int m=s.size()...算法原理: 1、状态表示(经验+题目要求) dp[i][j]表示:nums1以i位置为结尾的所有子数组以及nums2以j位置为结尾的所有子数组,最长重复子数组的长度。...=nums2[j]——>0 nums1[i]==nums2[j]——>dp[i-1][j-1]+1 3、初始化 都初始化为0即可 4、填表顺序 从上往下填每一行 每一行从左往右填 5、返回值 dp的最大值

4610
领券