1.左孩子右兄弟(树形dp)

image.png

  • 输入:

    5 1 1 1 2

  • 输出:

    4

2.思路分析

树形dp通常需要结合递归来实现,具体的实现方式参考:
https://www.bilibili.com/video/BV1Ci4y1g7H5?share_source=copy_web
树形dp的核心思想就是搜索!!!
从给出的样例我们可以直观的看出,最大的高度就是:将与根结点相连的节点全部连成一条线,然后找到与根节点相邻的节点中找到深度最长的接到线的最后面。
那么对于后面的节点来说,等同于寻找当前节点的最大深度。
注意:从这里我们可以发现,重复子问题出现了!,那么我们就可以通过递归来找到指定节点的最大深度,最大深度,dp[1]=与1节点相邻的节点的数量+相邻节点的最大深度。

3.代码

  • 自顶向下 ```java

    include

    using namespace std;

const int N = 100010;

int n; int f[N]; vector g[N];

void dfs(int u) {

  1. f[u] = g[u].size();
  2. int maxv = 0;
  3. for (int i = 0; i < g[u].size(); i ++)
  4. {
  5. int j = g[u][i];
  6. dfs(j);
  7. maxv = max(maxv, f[j]);
  8. }
  9. f[u] += maxv;

}

int main() {

  1. cin >> n;
  2. for (int i = 2; i <= n; i ++)
  3. {
  4. int u;
  5. cin >> u;
  6. g[u].push_back(i);
  7. }
  8. dfs(1);
  9. cout << f[1] << endl;
  10. return 0;

} ```