zoukankan      html  css  js  c++  java
  • 洛谷 P2015 二叉苹果树(树形dp)

    传送门


    解题思路

    很显然的树形dp,设dp[i][j]表示在子树i上保留j条边的最大苹果树,从儿子节点转移过来即可,注意若某个儿子不选,则以此儿子为根的子树都不能选。

    还有就是因为是二叉树,可以提前遍历一遍求出每个点的两个或零个儿子,就不用在求dp时倒序枚举了,算是一个小技巧趴。

    AC代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cmath>
     4 #include<cstdio>
     5 #include<cstring>
     6 using namespace std;
     7 int n,q,cnt,p[105],dp[105][105],son[105][3];
     8 struct node{
     9     int v,value,next;
    10 }e[205];
    11 void insert(int u,int v,int value){
    12     cnt++;
    13     e[cnt].v=v;
    14     e[cnt].value=value;
    15     e[cnt].next=p[u];
    16     p[u]=cnt;
    17 } 
    18 void dfs(int u,int fa){
    19     for(int i=p[u];i!=-1;i=e[i].next){
    20         int v=e[i].v;
    21         if(v==fa) continue;
    22         son[u][++son[u][0]]=i;
    23         dfs(v,u);
    24     }
    25 }
    26 void dfs2(int u){
    27     if(son[u][0]==0) return;
    28     int v1=e[son[u][1]].v;
    29     int v2=e[son[u][2]].v;
    30     dfs2(v1);
    31     dfs2(v2);
    32     for(int i=1;i<=q;i++){
    33         dp[u][i]=max(dp[v1][i-1]+e[son[u][1]].value,dp[v2][i-1]+e[son[u][2]].value);
    34         for(int j=0;j<=i-2;j++) dp[u][i]=max(dp[u][i],dp[v1][j]+dp[v2][i-2-j]+e[son[u][1]].value+e[son[u][2]].value);
    35     }
    36 }
    37 int main()
    38 {
    39     memset(p,-1,sizeof(p));
    40     cin>>n>>q;
    41     for(int i=1;i<=n-1;i++){
    42         int u,v,value;
    43         cin>>u>>v>>value;
    44         insert(u,v,value);
    45         insert(v,u,value);
    46     }
    47     dfs(1,-1);
    48     dfs2(1);
    49     cout<<dp[1][q];
    50     return 0;
    51 }
  • 相关阅读:
    手把手教您玩转信用卡 如何“以卡养卡”合法“套现”
    267家已获第三方许可机构名单查询
    C#生成图片验证码
    File I/O
    文件上传代码
    集合框架
    接口
    多态
    封装
    jsp做成mvc模式的代码
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/13844043.html
Copyright © 2011-2022 走看看