zoukankan      html  css  js  c++  java
  • 1561:The more, The Better

    Problem Description
    ACboy很喜欢玩一种战略游戏,在一个地图上,有N座城堡,每座城堡都有一定的宝物,在每次游戏中ACboy允许攻克M个城堡并获得里面的宝物。但由于地理位置原因,有些城堡不能直接攻克,要攻克这些城堡必须先攻克其他某一个特定的城堡。你能帮ACboy算出要获得尽量多的宝物应该攻克哪M个城堡吗?
     

    Input
    每个测试实例首先包括2个整数,N,M.(1 <= M <= N <= 200);在接下来的N行里,每行包括2个整数,a,b. 在第 i 行,a 代表要攻克第 i 个城堡必须先攻克第 a 个城堡,如果 a = 0 则代表可以直接攻克第 i 个城堡。b 代表第 i 个城堡的宝物数量, b >= 0。当N = 0, M = 0输入结束。
     

    Output
    对于每个测试实例,输出一个整数,代表ACboy攻克M个城堡所获得的最多宝物的数量。
     

    Sample Input

    3 2 0 1 0 2 0 3 7 4 2 2 0 1 0 4 2 1 7 1 7 6 2 2 0 0

     

    Sample Output

    5 13

     

    Author
    8600
     

    Source
    HDU 2006-12 Programming Contest

    树形依赖背包基础题

    首先先讲一下泛型物品,就是这个物品并不是不变的,你给他v的花费,他给你h[v]的价值,这个大家应该很熟悉吧

    然后就是树形依赖背包了,就是每个物品必须在他的父亲被选了之后才能选

    一般我们用很基本的方法,就是设f[i,j]表示这颗子树用j的花费可以得到的价值,然后很容易得到一个O(n*v^2)的算法

    但是如果是这样还不够好,于是就有了O(n*v)的算法

    其实我们发现每个节点都是一个泛型物品,我们要做的是泛型物品的和,所以是O(v^2)的

    我们有更好的做法

    假设s是i的儿子我们就先给f[s]赋一个初值,强制选物品s,和f[i]合起来,这样是O(v)的,然后dfs(s),然后再O(v)求f[i]和f[s]的并

    这样做就是O(n*v)的啦

     1 const
     2     maxn=220;
     3 var
     4     f:array[0..maxn,0..maxn]of longint;
     5     first,last,next,a:array[0..maxn]of longint;
     6     n,m,tot:longint;
     7 
     8 procedure insert(x,y:longint);
     9 begin
    10     inc(tot);
    11     last[tot]:=y;
    12     next[tot]:=first[x];
    13     first[x]:=tot;
    14 end;
    15 
    16 function max(x,y:longint):longint;
    17 begin
    18     if x>y then max:=x
    19     else max:=y;
    20 end;
    21 
    22 procedure dfs(x,m:longint);
    23 var
    24     i,j:longint;
    25 begin
    26     i:=first[x];
    27     while i<>0 do
    28       begin
    29         for j:=0 to m-1 do
    30           f[last[i],j]:=f[x,j];
    31         dfs(last[i],m-1);
    32         for j:=1 to m do
    33           f[x,j]:=max(f[x,j],f[last[i],j-1]+a[last[i]]);
    34         i:=next[i];
    35       end;
    36 end;
    37 
    38 procedure main;
    39 var
    40     i,x:longint;
    41 begin
    42     for i:=0 to n do first[i]:=0;
    43     tot:=0;
    44     for i:=1 to n do
    45       begin
    46         read(x,a[i]);
    47         insert(x,i);
    48       end;
    49     for i:=0 to m do f[0,i]:=0;
    50     dfs(0,m);
    51     writeln(f[0,m]);
    52     read(n,m);
    53 end;
    54 
    55 begin
    56     read(n,m);
    57     while n<>0 do
    58       main;
    59 end.
    View Code
  • 相关阅读:
    hdu1430 魔板(康拓展开 bfs预处理)
    网络流EdmondsKarp算法模板理解
    poj3020 建信号塔(匈牙利算法 最小覆盖边集)
    bzoj 2465 小球
    bzoj 1822 冷冻波
    bzoj 1040 骑士
    Codeforces Round #460 (Div. 2)
    bzoj 1072 排列perm
    Codeforces Round #459 (Div. 2)
    bzoj 1087 互不侵犯King
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3798841.html
Copyright © 2011-2022 走看看