• Codeforces1065F Up and Down the Tree 【树形DP】


    推荐一道联赛练习题。

    题目分析:

    你考虑进入一个子树就可能上不来了,如果上得来的话就把能上来的全捡完然后走一个上不来的,所以这就是个基本的DP套路。

    代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 const int maxn = 1002000;
     5 
     6 int n,k,fa[maxn];
     7 vector <int> g[maxn];
     8 
     9 int dep[maxn],minn[maxn];
    10 
    11 int f[maxn],d[maxn];
    12 
    13 void read(){
    14     scanf("%d%d",&n,&k);
    15     for(int i=2;i<=n;i++) {scanf("%d",&fa[i]);g[fa[i]].push_back(i);}
    16 }
    17 
    18 void dfs(int now,int dp){
    19     dep[now] = dp;
    20     if(g[now].size() == 0){minn[now] = dp; return;}
    21     minn[now] = 1e8;
    22     for(int i=0;i<g[now].size();i++){
    23     dfs(g[now][i],dp+1);
    24     minn[now] = min(minn[now],minn[g[now][i]]);
    25     }
    26 }
    27 
    28 void dfs2(int now){
    29     if(g[now].size() == 0){
    30     f[now] = d[now] = 1;
    31     return;
    32     }
    33     for(int i=0;i<g[now].size();i++) dfs2(g[now][i]);
    34     for(int i=0;i<g[now].size();i++)
    35     if(minn[g[now][i]] - dep[now] <= k) d[now] += d[g[now][i]];
    36     for(int i=0;i<g[now].size();i++){
    37     if(minn[g[now][i]] - dep[now] <= k)
    38         f[now] = max(f[now],d[now]-d[g[now][i]]+f[g[now][i]]);
    39     else f[now] = max(f[now],d[now]+f[g[now][i]]);
    40     }
    41 }
    42 
    43 void work(){
    44     dfs(1,1);
    45     dfs2(1); // dp
    46     printf("%d
    ",f[1]);
    47 }
    48 
    49 int main(){
    50     read();
    51     work();
    52     return 0;
    53 }
  • 相关阅读:
    AJAX
    正则表达式
    SQL
    foreach 的本质
    C#
    Dojo的subscribe和publish的简单使用
    Dojo的Gridx使用jsonrest需要注意的地方
    如何让Button使用自定义icon
    Djanog结合jquery实现ajax
    如何设置静态文件路径
  • 原文地址:https://www.cnblogs.com/Menhera/p/9835604.html
Copyright © 2020-2023  润新知