zoukankan      html  css  js  c++  java
  • 树形dp mark

    A - Anniversary party HDU - 1520 

    题意是 有一个树 每个点都有一个价值,选了父亲节点就不能选子节点 选了子节点就不能选父亲节点 

    问最后能得到的最大价值是多少

    树形dp入门  定义状态 dp[i][1]表示选中此节点 dp[i][0]表示未选中此节点

    那么 dp[i][1]=sigma(dp[j][0])+a[i]; //j为i的儿子节点

    dp[i][0]=sigma(max(dp[j][1],dp[j][0]))+a[i];

    另外无论如何都要吐槽一下这题的输入格式!!!!

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int n;
     4 const int maxn=6060;
     5 
     6 vector<int>G[maxn];
     7 int v[6060];
     8 int dp[maxn][2];
     9 int pre[maxn];
    10 
    11 int dfs(int x)
    12 {
    13     dp[x][1]=v[x];
    14     for(int i=0;i<G[x].size();i++)
    15         dfs(G[x][i]);
    16     for(int i=0;i<G[x].size();i++)
    17     {
    18         dp[x][1]+=dp[G[x][i]][0];
    19         dp[x][0]+=max(dp[G[x][i]][1],dp[G[x][i]][0]);
    20     }
    21 }
    22 
    23 int main()
    24 {
    25     int x,y;
    26     while(~scanf("%d",&n)){
    27     for(int i=0;i<=n;i++) G[i].clear();
    28     for(int i=1;i<=n;i++) scanf("%d",&v[i]);
    29     memset(pre,-1,sizeof(pre));
    30     while(~scanf("%d%d",&x,&y))
    31     {
    32         if(x==0||y==0) break;
    33         G[y].push_back(x);
    34         pre[x]=y;
    35     }
    36 
    37     memset(dp,0,sizeof(dp));
    38 
    39     int root=1;
    40     while(pre[root]!=-1) root=pre[root];
    41     dfs(root);
    42     printf("%d
    ",max(dp[root][0],dp[root][1]));
    43 }
    44 }

    B - Computer

     HDU - 2196 

    给一个树 求每个节点能够到达的最远距离是多少?

    定义dp[i][0]为i节点向下走的最远距离,自下而上

    dp[i][1]为i节点向下走的次远距离,自下而上

    dp[i][2]为i节点向上走的最远距离,自上而下

    那么每一个节点能够到达的最远距离与 儿子节点到达的距离有关 与父亲节点到达的距离有关

    那么就需要两次dfs , 第一次自下而上 维护一个 dp[i][0],dp[i][1],

    第二次dfs 自上而下 维护一下 dp[i][2];

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 
     4 typedef pair<int,int> pii;
     5 
     6 const int maxn=1e4+5;
     7 
     8 int n;
     9 vector<pii >G[maxn];
    10 
    11 int dp[maxn][3];
    12 
    13 int dfs1(int u)
    14 {
    15     for(int i=0;i<G[u].size();i++)
    16     {
    17         int v=G[u][i].first;
    18         int w=G[u][i].second;
    19         dfs1(v);
    20         if(dp[u][0]<=dp[v][0]+w)
    21         {
    22             dp[u][1]=dp[u][0];
    23             dp[u][0]=dp[v][0]+w;
    24         }
    25         else if(dp[v][0]+w>dp[u][1])
    26             dp[u][1]=dp[v][0]+w;
    27     }
    28 }
    29 
    30 int dfs2(int u)
    31 {
    32     for(int i=0;i<G[u].size();i++)
    33     {
    34         int v=G[u][i].first;
    35         int w=G[u][i].second;
    36         if(dp[u][0]!=dp[v][0]+w)
    37         {
    38             dp[v][2]=max(dp[u][0]+w,dp[u][2]+w);
    39         }
    40         else{
    41             dp[v][2]=max(dp[u][1]+w,dp[u][2]+w);
    42         }
    43         dfs2(v);
    44     }
    45 }
    46 
    47 int main()
    48 {
    49     int x,y;
    50     while(~scanf("%d",&n))
    51     {
    52         for(int i=0;i<=n;i++) G[i].clear();
    53         for(int i=2;i<n+1;i++)
    54         {
    55             scanf("%d%d",&x,&y);
    56             G[x].push_back({i,y});
    57         }
    58 
    59         memset(dp,0,sizeof(dp));
    60 
    61         dfs1(1);
    62         dfs2(1);
    63 
    64         for(int i=1;i<=n;i++)
    65             printf("%d
    ",max(dp[i][0],dp[i][2]));
    66     }
    67 }
  • 相关阅读:
    LeetCode 485. Max Consecutive Ones
    LeetCode 367. Valid Perfect Square
    LeetCode 375. Guess Number Higher or Lower II
    LeetCode 374. Guess Number Higher or Lower
    LeetCode Word Pattern II
    LeetCode Arranging Coins
    LeetCode 422. Valid Word Square
    Session 共享
    java NIO
    非阻塞IO
  • 原文地址:https://www.cnblogs.com/hellohacker/p/7379835.html
Copyright © 2011-2022 走看看