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
原文地址:https://www.cnblogs.com/Randolph87/p/3798841.html