• CODEVS5565 二叉苹果树


    n<=100个点的根为1的二叉树,树边上有苹果,求保留Q<=n条边的最多苹果数。

    树形DP,f[i][j]--节点i为根的子树保留j条边最优方案,f[i][0]=0,f[i][j]=max(f[lc[i]][k-1]+f[rc[i]][j-k-1]+v[lc[i]]+v[rc[i]]),这是左右都选的情况,再加只选左只选右方案即可。

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 #include<algorithm>
     5 //#include<iostream>
     6 using namespace std;
     7 
     8 int n,Q;
     9 #define maxn 111
    10 int f[maxn][maxn];
    11 struct Edge{int to,next,v;};
    12 struct Tree
    13 {
    14     Edge edge[maxn<<1];
    15     int lc[maxn],rc[maxn],v[maxn];
    16     int first[maxn],le;
    17     Tree() {memset(first,0,sizeof(first));le=2;}
    18     void in(int x,int y,int v)
    19     {
    20         edge[le].to=y;
    21         edge[le].v=v;
    22         edge[le].next=first[x];
    23         first[x]=le++;
    24     }
    25     void insert(int x,int y,int v)
    26     {
    27         in(x,y,v);
    28         in(y,x,v);
    29     }
    30     void dfs(int x,int fa)
    31     {
    32         lc[x]=rc[x]=0;
    33         for (int i=first[x];i;i=edge[i].next)
    34             if (edge[i].to!=fa)
    35             {
    36                 if (!lc[x]) lc[x]=edge[i].to;
    37                 else rc[x]=edge[i].to;
    38                 v[edge[i].to]=edge[i].v;
    39                 dfs(edge[i].to,x);
    40             }
    41     }
    42     void dp(int x)
    43     {
    44         if (lc[x]) dp(lc[x]);
    45         if (rc[x]) dp(rc[x]);
    46         f[x][0]=0;
    47         for (int i=1;i<=Q;i++)
    48         {
    49             f[x][i]=max(f[lc[x]][0]+f[rc[x]][i-1]+v[rc[x]],f[lc[x]][i-1]+f[rc[x]][0]+v[lc[x]]);
    50             for (int j=1;j<=i-1;j++)
    51                 f[x][i]=max(f[x][i],f[lc[x]][j-1]+f[rc[x]][i-j-1]+v[lc[x]]+v[rc[x]]);
    52         }
    53     }
    54 }t;
    55 int x,y,v;
    56 int main()
    57 {
    58     scanf("%d%d",&n,&Q);
    59     for (int i=1;i<n;i++)
    60     {
    61         scanf("%d%d%d",&x,&y,&v);
    62         t.insert(x,y,v);
    63     }
    64     t.dfs(1,0);
    65     t.dp(1);
    66     printf("%d
    ",f[1][Q]);
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    数论知识点--以及模板
    【数学+思维】ZZULIOJ 1531: 小L的区间求和
    记忆化搜索模板题---leetcode 1155. 掷骰子的N种方法
    拓扑排序
    ZOJ
    multiset的应用
    HDU
    HDU
    D. Beautiful Array
    HDU
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7354764.html
Copyright © 2020-2023  润新知