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
  • 相关阅读:
    jquery实现选项卡(两句即可实现)
    常用特效积累
    jquery学习笔记
    idong常用js总结
    织梦添加幻灯片的方法
    LeetCode "Copy List with Random Pointer"
    LeetCode "Remove Nth Node From End of List"
    LeetCode "Sqrt(x)"
    LeetCode "Construct Binary Tree from Inorder and Postorder Traversal"
    LeetCode "Construct Binary Tree from Preorder and Inorder Traversal"
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3798841.html
Copyright © 2011-2022 走看看