一道入门的树形DP。

首先我们对于数据进行有序化处理,这便于我们利用数据结构特点(可排序性)来发觉数据性质(有序、单调、子问题等等性质),以便于后续的转化、推理和处理。有序化可以“转化和创造”性质

首先将视角从无根树切换为有根树,这样我们就可以得到一个带有最优子结构、无后效性、子问题重叠性的结构——一个根和一堆子树。

由于我们是要求联通分量的最大值,我们观察到每一个联通分量都可以看做一个有根树,这就保证了树形DP的正确性。(后面会再解释)

不难想到令\(f_i\)表示包含该位置的、以\(i\)号节点为根的子树的最大值。

这里的“不难想到”其实有两种想法——第一种是树形DP的一般思路就是子啊一棵子树内处理根与子树的关系,这是一种常见的经验或者说手法。第二种想法就是说,连通分量可以转化成更小的联通分量,加上有序化之后,变成了子树层层求解。

我们考虑每一棵子树,不难发现初始化每个节点就是根节点自己的值,然后对于每一棵向下连接根节点的子树的最大值,如果大于零,那么我们就把根通向这棵子树的边连接起来。

令\(j\)为\(i\)子树根节点的编号,有$f_i = \sum f_j \times [f_j > 0] $

关于正确性,可能会有问题:对于一棵子树而言,我们只考虑了这些向下的分支,并没有考虑向上父节点的这支“分支”,感觉不太对劲?

实际上,我们要明确我们这里求的是一个小范围内子问题的最优解,不是全局最优解。如果每个点都考虑所有的分支情况(包括向上找父亲的那个分支),那么所有的点都是在求全局最优解,这样就无法进行DP或者状态转移了, 问题也没有得到简化。

我们考虑所谓“向上”的分支,实际上就是上面“向下”的分支,所以这种情况显然是可以被覆盖到的。如果上面的向下伸的这个分支是断的,没有到达这个子树的根节点,那么这棵子树加上向上一段的分支最大也会是负的,显然单独的子树或者单独的上面那个点都是更优的,不会有贡献。

实际上,我们陷入这种思维泥潭的主要原因还是不清楚DP的逻辑——DP的局部最优解是为全局服务的,这个局部最优解是在某种定义下成立的,不代表全局最优,但是可以求出全局最优。就比如这道题里面的局部最优解就不包括向上的分支,它只考虑这一棵子树内的情况,这样保证了问题的规模从小到大,保证了其他可以DP的性质。

思考DP算法,某种意义上而言,是一种构建数学和逻辑的“自动机”的过程。

DP可以从经验出发,可以从DP性质出发, 也可以从问题本身的性质出发,三者相互联系,加上一些转化或者优化的技巧可以求解。

总结:树形DP的一种一般分析方法是有序化(有根树)后考虑子树上跟和子树的关系转移;可以从小规模子问题入手;定义一种可以转移的状态(意义),并确定初始值和转移方法;时刻清楚讨论的问题和环境是什么,比如在局部最优中讨论整体最优就是无太大意义的,因为DP中不需要考虑

一种步骤:转化、子问题、状态、转移方程、优化

要格外注意递归中的“回头找”和计算和的关系。在这里是,不能把判断vis放到开头,不但多递归一层,就会多计算一层和。

源码:


#include <bits/stdc++.h> #define N (int)(16005) using namespace std; typedef long long LL; LL a[N]; vector<int> e[N]; LL f[N]; LL ans; bool vis[N]; void dfs(int p)
{
ans = max(ans,f[p]);
vis[p] = true;
vis[p] = true;
//cout << p << "\n";
for(int i = 0;i < e[p].size();i++)
{
int q = e[p][i];
if(vis[q]) continue;
dfs(q);
//cout << p << " " << q << " " << f[p] << " " << f[q] << "\n";
if(f[q] > 0) f[p] += f[q];
ans = max(ans,f[p]);
}
} int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n;
cin >> n;
memset(f,0x8f,sizeof(f));
memset(vis,0,sizeof(vis));
ans = -1e18;
for(int i = 1;i <= n;i++)
{
cin >> a[i];
f[i] = a[i];
}
for(int i = 1;i <= n-1;i++)
{
int x,y;
cin >> x >> y;
e[x].push_back(y);
e[y].push_back(x);
}
dfs(1);
cout << ans << "\n";
return 0;
}

洛谷 P1122 最大子树和 题解的更多相关文章

  1. 洛谷P1122最大子树和题解

    题目 一道比较好想的树形\(DP\) 完全可以用树形DP的基本思路,递归,然后取最优的方法. \(Code\) #include <iostream> #include <cstri ...

  2. 洛谷P1122 最大子树和

    P1122 最大子树和 题目提供者该用户不存在 标签动态规划树形结构 难度普及/提高- 通过/提交54/100 提交该题 讨论 题解 记录 题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在 ...

  3. 洛谷 P1122 最大子树和

    P1122 最大子树和 题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的 ...

  4. 洛谷——P1122 最大子树和

    P1122 最大子树和 树形DP,$f[u]$表示以u为根的子树的最大美丽指数 $f[u]+=max(0,f[v])$ 树形DP的基本结构,先搜再DP,这题感觉有点儿贪心的性质,选就要选美丽值> ...

  5. 洛谷P1122 最大子树和 (树状dp)

    题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明 ...

  6. 洛谷—— P1122 最大子树和

    https://www.luogu.org/problem/show?pid=1122 题目描述 小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课 ...

  7. 洛谷P1122 最大子树和 树形DP初步

    小明对数学饱有兴趣,并且是个勤奋好学的学生,总是在课后留在教室向老师请教一些问题.一天他早晨骑车去上课,路上见到一个老伯正在修剪花花草草,顿时想到了一个有关修剪花卉的问题.于是当日课后,小明就向老师提 ...

  8. 洛谷P1783 海滩防御 分析+题解代码

    洛谷P1783 海滩防御 分析+题解代码 题目描述: WLP同学最近迷上了一款网络联机对战游戏(终于知道为毛JOHNKRAM每天刷洛谷效率那么低了),但是他却为了这个游戏很苦恼,因为他在海边的造船厂和 ...

  9. 洛谷P4047 [JSOI2010]部落划分题解

    洛谷P4047 [JSOI2010]部落划分题解 题目描述 聪聪研究发现,荒岛野人总是过着群居的生活,但是,并不是整个荒岛上的所有野人都属于同一个部落,野人们总是拉帮结派形成属于自己的部落,不同的部落 ...

  10. 洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈)

    洛谷P1155 双栈排序题解(图论模型转换+二分图染色+栈) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1311990 原题地址:洛谷P1155 双栈排序 ...

随机推荐

  1. Prompt learning 教学[进阶篇]:简介Prompt框架并给出自然语言处理技术:Few-Shot Prompting、Self-Consistency等;项目实战搭建知识库内容机器人

    Prompt learning 教学[进阶篇]:简介Prompt框架并给出自然语言处理技术:Few-Shot Prompting.Self-Consistency等:项目实战搭建知识库内容机器人 1. ...

  2. 2020-10-21:go中channel的send流程是什么?

    福哥答案2020-10-21: ***[评论](https://user.qzone.qq.com/3182319461/blog/1603234689)

  3. 2022-06-17:给定一个数组arr,含有n个数字,可能有正、有负、有0, 给定一个正数k。 返回所有子序列中,累加和最大的前k个子序列累加和。 假设K不大,怎么算最快? 来自Amazon。

    2022-06-17:给定一个数组arr,含有n个数字,可能有正.有负.有0, 给定一个正数k. 返回所有子序列中,累加和最大的前k个子序列累加和. 假设K不大,怎么算最快? 来自Amazon. 答案 ...

  4. 为什么 GPU 能够极大地提高仿真速度?

    这里的提速主要是针对时域电磁算法的.因为时域算法的蛙跳推进模式仅对大量存放在固定 位置的数据进行完全相同的且是简单的操作(移位相加),这正是 GPU 这类众核 SIMD 架构所进行的运算,即 ALU ...

  5. linux 系统安全和应用

    目录 一.系统安全 二.账号安全 三.修改密码生效时间 四.强制下次登录成功时修改密码 五.历史命令 六.终端自动注销 七.wheel组 八.grub菜单密码 一.系统安全 原因:1.系统数据想要保护 ...

  6. wireshark分析tcp传输之文件上传速率问题

    在网络性能问题排查思路那一节里,我提到了查看系统网络瓶颈的方法以及排查丢包问题的手段. 但就此分析网络问题还不够精细,有时网络资源并没有达到瓶颈,或者并没有丢包产生,但是网络传输速率就是很慢,或者有丢 ...

  7. 杭电多校第二场 DOS Card

    杭电多校第二场 DOS Card 评价一下这道题:我写过最爽的线段树题. 这道题真的非常令人身心愉悦,非常厉害的一道线段树入门题.我写这个一次调试都没有,过了样例就交了就过了,一切都是行云流水. 这道 ...

  8. 一文吃透Java并发高频面试题

    内容摘自我的学习网站:topjavaer.cn 分享50道Java并发高频面试题. 线程池 线程池:一个管理线程的池子. 为什么平时都是使用线程池创建线程,直接new一个线程不好吗? 嗯,手动创建线程 ...

  9. go语言编写算法

    1.冒泡排序 // 冒泡排序 a := []uint8{9, 20, 10, 23, 7, 22, 88, 102} for i := 0; i < len(a); i++ { for k := ...

  10. Instruments中常用Template的使用

     Instruments是苹果提供的Xcode套件,可用于分析iOS,MacOS程序的性能数据,进行性能提升.Instruments提供了很多类型的Template,用于特定场景的分析.这里选了3种常 ...