zoukankan      html  css  js  c++  java
  • P1676陶陶吃苹果


    描述

    curimit知道陶陶很喜欢吃苹果。于是curimit准备在陶陶生日的时候送给他一棵苹果树。

    curimit准备了一棵这样的苹果树作为生日礼物:这棵苹果树有n个节点,每个节点上有c[i]个苹果,这棵树高度为h。

    可是,当curimit把这棵树给陶陶看的时候,陶陶却说:“今年生日不收礼,收礼只收节点数减高度不超过k的苹果树。”这下curimit犯难了,curimit送来的树枝繁叶茂,不满足节点数-高度≤k。于是curimit决定剪掉一些枝条,使得修剪过后的树满足节点数-高度≤k,但是curimit又想保留尽量多的苹果数目。curimit想请你帮他算算经过修剪后的树最多能保留多少个苹果。

    注:
    一, 节点1为树根,不能把它剪掉。

    二, 1个节点的树高度为1。
    格式
    输入格式

    输入文件的第一行为两个整数n,k分别表示这棵树有n个节点,修剪后的树节点数-高度≤k。

    第二行开始到第n+1行,每行有两个数,第i+1行的两个数father[i]和c[i]分别表示节点i的父亲是father[i]和节点i处有c[i]个苹果。

    规定:节点1的父亲为0。
    输出格式

    输出文件仅包含一行,ans,表示在满足修建后的树节点数-高度≤k的条件下,最多能保留多少个苹果。
    样例1
    样例输入1[复制]

        5 1
        0 1
        1 1
        1 3
        2 10
        3 4

    样例输出1[复制]

        15

    限制

    全部1秒
    提示

    【约定】
    对于10%的数据, n≤10
    对于30%的数据, n≤100 0≤k≤20
    对于100%的数据,n≤4000 0≤k≤=500

    神啦,树形依赖背包还可以出成这样

    我们回忆我们怎么做树形依赖背包的

    s是i的儿子,f[s]的初值为f[i],dfs(s),然后f[i,v]:=min(f[i,v],f[i,v-1]+a[s])

    这样的话我们发现叶子节点存的f其实就是处理了这条链左边的节点所得到的信息

    仔细观察题目条件,我们发现这个是树形依赖背包,但是有一条链免费,所以我们dfs两次,一次从左往右,一次从右往左

    然后我们枚举免费的链,只枚举根到叶子节点的(1.我们只能保证叶子节点有上面这个性质2.免费的链当然是越深越好啦),然后更新答案

    orz出题人

     1 const
     2     maxn=4040;
     3     maxk=550;
     4 var
     5     fl,fr:array[0..maxn,0..maxk]of longint;
     6     v:array[0..maxn,0..maxn]of longint;
     7     a,sum,f:array[0..maxn]of longint;
     8     n,k,ans:longint;
     9 
    10 function max(x,y:longint):longint;
    11 begin
    12     if x>y then exit(x);
    13     exit(y);
    14 end;
    15 
    16 procedure dfsl(x:longint);
    17 var
    18     i,j:longint;
    19 begin
    20     sum[x]:=sum[f[x]]+a[x];
    21     for i:=1 to v[x,0] do
    22         begin
    23             for j:=0 to k do
    24                 fl[v[x,i],j]:=fl[x,j];
    25             dfsl(v[x,i]);
    26             for j:=1 to k do
    27                 fl[x,j]:=max(fl[x,j],fl[v[x,i],j-1]+a[v[x,i]]);
    28         end;
    29 end;
    30 
    31 procedure dfsr(x:longint);
    32 var
    33     i,j:longint;
    34 begin
    35     for i:=v[x,0] downto 1 do
    36         begin
    37             for j:=0 to k do
    38                 fr[v[x,i],j]:=fr[x,j];
    39             dfsr(v[x,i]);
    40             for j:=1 to k do
    41                 fr[x,j]:=max(fr[x,j],fr[v[x,i],j-1]+a[v[x,i]]);
    42         end;
    43 end;
    44 
    45 procedure main;
    46 var
    47     i,x:longint;
    48 begin
    49     read(n,k);
    50     for i:=1 to n do
    51         begin
    52             read(f[i],a[i]);
    53             inc(v[f[i],0]);v[f[i],v[f[i],0]]:=i;
    54         end;
    55     dfsl(1);
    56     dfsr(1);
    57     for i:=1 to n do
    58         if v[i,0]=0 then
    59         for x:=0 to k do
    60             ans:=max(ans,fl[i,x]+fr[i,k-x]+sum[i]);
    61     writeln(ans);
    62 end;
    63 
    64 begin
    65     main;
    66 end.
    View Code
  • 相关阅读:
    Codechef EDGEST 树套树 树状数组 线段树 LCA 卡常
    BZOJ4319 cerc2008 Suffix reconstruction 字符串 SA
    Codechef STMINCUT S-T Mincut (CodeChef May Challenge 2018) kruskal
    Codeforces 316G3 Good Substrings 字符串 SAM
    Codechef CHSIGN Change the Signs(May Challenge 2018) 动态规划
    BZOJ1396 识别子串 字符串 SAM 线段树
    CodeForces 516C Drazil and Park 线段树
    CodeForces 516B Drazil and Tiles 其他
    CodeForces 516A Drazil and Factorial 动态规划
    SPOJ LCS2
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3799425.html
Copyright © 2011-2022 走看看