动态规划之【树形DP】第2课树形DP应用案例实践1二叉苹果树题目描述有一棵苹果树如果树枝有分叉一定是分二叉就是说没有只有一个儿子的结点这棵树共有N NN个结点叶子点或者树枝分叉点编号为1 ∼ N 1 \sim N1∼N树根编号一定是1 11。我们用一根树枝两端连接的结点的编号来描述一根树枝的位置。下面是一颗有4 44个树枝的树2 5 \ / 3 4 \ / 1现在这颗树枝条太多了需要剪枝。但是一些树枝上长有苹果。给定需要保留的树枝数量求出最多能留住多少苹果。留住一个苹果的定义为苹果所在枝条直接与根相连或通过其他枝条间接与根相连。输入格式第一行2 22个整数N NN和Q QQ分别表示表示树的结点数和要保留的树枝数量。接下来N − 1 N-1N−1行每行3 33个整数描述一根树枝的信息前2 22个数是它连接的结点的编号第3 33个数是这根树枝上苹果的数量。输出格式一个数最多能留住的苹果的数量。输入输出样例 #1输入 #15 2 1 3 1 1 4 10 2 3 20 3 5 20输出 #121说明/提示1 ⩽ Q N ⩽ 100 1 \leqslant Q N \leqslant 1001⩽QN⩽100每根树枝上的苹果⩽ 3 × 10 4 \leqslant 3 \times 10^4⩽3×104。思路分析题目描述给定一棵二叉树每条树枝上有若干苹果。要求保留m条树枝即边使得剩下的苹果总数最大。剪枝规则是若剪掉某条树枝则其子树上的所有树枝都会被剪掉。题目分析​ 留q个树枝转换为留q1个结点​ 把树枝上的苹果数转换到结点上​ 对于树中的每棵子树要保留j个结点 因为根必须保留所以需要保留j-1个子结点如果左子树保留k个结点则右子树需保留j-1-k个结点状态定义dp[i][j]表示以节点i为根的子树保留j个结点时的最大苹果数。状态转移方程dp[i][j]max(dp[i][j],dp[L[i]][k]dp[R[i]][j-1-k]a[i])其中0≤k≤j-1 L[i]表示i结点的左儿子 R[i]表示i结点的右儿子 边界条件 j0时dp[i][0]0//保留0个结点j!0L[i]0R[i]0时dp[i][j]a[i]//叶子结点最终求解的答案为 dp[1][q1]实现步骤1.核心逻辑问题转化将边权值转化为子节点的权值保留子节点即意味着保留其父边。树形DP通过递归分治将问题分解为左右子树的子问题利用记忆化避免重复计算。2.数据结构与初始化使用邻接矩阵a存储树的边及其权值苹果数。L和R数组分别记录每个节点的左、右子节点。w数组存储每个节点到其父节点的边权值。dp[i][j]为动态规划数组表示以节点i为根的子树保留j个节点时的最大苹果数。3.建树过程DFS通过深度优先搜索遍历树将每个节点的子节点转换为二叉树结构记录左、右子节点并存储对应边的权值到w数组中。4.动态规划记忆化搜索函数f(i, j)递归计算以i为根的子树保留j个节点的最大苹果数。状态转移枚举左子树保留k个节点右子树保留j-1-k个节点当前节点占1个取左右子树最大值之和加上当前节点的权值w[i]。边界条件叶子节点直接返回其权值保留0个节点返回0。5.输入输出处理输入边信息构建邻接矩阵并转换为二叉树结构。最终输出f(1, q1)因为保留q条边对应保留q1个节点确保根节点必须保留。代码实现#includebits/stdc.husingnamespacestd;intn,q,x,y,z;intL[110],R[110];//存结点的左右儿子inta[110][110];//邻接矩阵intdp[110][110];//dp[i][j]:表示以节点 i为根的子树保留 j个结点时的最大苹果数intw[110];//结点的苹果数//建树voiddfs(intx,intfa){//x是结点编号fa是x的父结点编号for(inti1;in;i){if(a[x][i]!-1i!fa){if(L[x]0){L[x]i;//i是x的左孩子w[i]a[x][i];//i结点的苹果数}elseif(R[x]0){R[x]i;//i是x的右孩子w[i]a[x][i];//i结点的苹果数}dfs(i,x);}}}//i结点为根的子树保留j个结点的最大苹果树intf(inti,intj){if(j0)return0;//保留0个结点if(L[i]0R[i]0)returnw[i];//叶子结点if(dp[i][j]!-1)returndp[i][j];//记忆化递归for(intk0;kj-1;k){dp[i][j]max(dp[i][j],f(L[i],k)f(R[i],j-1-k)w[i]);}returndp[i][j];}intmain(){cinnq;memset(a,-1,sizeof(a));//a数组初始化memset(dp,-1,sizeof(dp));//dp数组初始化for(inti1;in-1;i){cinxyz;a[x][y]z;//无向图a[y][x]z;}//建树dfs(1,0);//1是根结点0表示根结点没有父亲//输出答案coutf(1,q1);return0;}完整系列资料请查看专栏《csp信奥赛C动态规划》https://blog.csdn.net/weixin_66461496/category_13096895.html各种学习资料助力大家一站式学习和提升#includebits/stdc.husingnamespacestd;intmain(){cout########## 一站式掌握信奥赛知识! ##########;cout############# 冲刺信奥赛拿奖! #############;cout###### 课程购买后永久学习不受限制! ######;return0;}【秘籍汇总】完整csp信奥赛C学习资料1、csp/信奥赛C完整信奥赛系列课程永久学习https://edu.csdn.net/lecturer/7901 点击跳转2、CSP信奥赛C竞赛拿奖视频课https://edu.csdn.net/course/detail/40437 点击跳转https://edu.csdn.net/course/detail/41081 点击跳转3、csp信奥赛高频考点知识详解及案例实践CSP信奥赛C动态规划https://blog.csdn.net/weixin_66461496/category_13096895.html点击跳转CSP信奥赛C标准模板库STLhttps://blog.csdn.net/weixin_66461496/category_13108077.html 点击跳转信奥赛C提高组csp-s知识详解及案例实践https://blog.csdn.net/weixin_66461496/category_13113932.html 点击跳转4、csp信奥赛冲刺一等奖有效刷题题解CSP信奥赛C初赛及复赛高频考点真题解析持续更新https://blog.csdn.net/weixin_66461496/category_12808781.html 点击跳转信奥赛C提高组csp-s初赛复赛真题题解持续更新https://blog.csdn.net/weixin_66461496/category_13125089.html 点击跳转5、GESP C考级真题题解GESP(C 一级二级三级)真题题解持续更新https://blog.csdn.net/weixin_66461496/category_12858102.html 点击跳转GESP(C 四级五级六级)真题题解持续更新https://blog.csdn.net/weixin_66461496/category_12869848.html 点击跳转GESP(C 七级八级)真题题解持续更新https://blog.csdn.net/weixin_66461496/category_13117178.html 点击跳转· 文末祝福 ·#includebits/stdc.husingnamespacestd;intmain(){cout跟着王老师一起学习信奥赛C;cout 成就更好的自己 ;cout csp信奥赛一等奖属于你! ;return0;}