很老的一道树DP,用树形DP的模型做,今天再写的时候居然沙茶的在计算过某状态后又重新计算,DP退化成了搜索,无奈。
转成二叉树后枚举左右子树分配的资源量即可。
View Code
1 program ctsc(input,output);
2 var
3 n,m : longint;
4 w,v : array[0..601] of longint;
5 left,right : array[0..601] of longint;
6 f : array[-100..601,-100..601] of longint;
7 procedure init;
8 var
9 i,x : longint;
10 begin
11 fillchar(f,sizeof(f),0);
12 readln(n,m);
13 for i:=0 to n do
14 begin
15 left[i]:=-1;
16 right[i]:=-1;
17 end;
18 for i:=1 to n do
19 begin
20 readln(x,w[i]);
21 if left[x]<>-1 then
22 right[i]:=left[x];
23 left[x]:=i;
24 end;
25 for i:=1 to n do
26 v[i]:=1;
27 v[0]:=0;
28 end; { init }
29 procedure dfs(now,worth :longint );
30 var
31 i : longint;
32 begin
33 if (now=-1)or(worth<=0) then
34 exit;
35 if f[now,worth]<>0 then//考试时就没写这句
36 exit;
37 dfs(left[now],worth-v[now]);
38 f[now,worth]:=f[left[now],worth-v[now]]+w[now];
39 dfs(right[now],worth);
40 if f[right[now],worth]>f[now,worth] then
41 f[now,worth]:=f[right[now],worth];
42 for i:=0 to worth-v[now] do
43 begin
44 dfs(left[now],i);
45 dfs(right[now],worth-v[now]-i);
46 if f[left[now],i]+f[right[now],worth-i-v[now]]+w[now]>f[now,worth] then
47 f[now,worth]:=f[left[now],i]+f[right[now],worth-i-v[now]]+w[now];
48 end;
49 end; { dfs }
50 begin
51 init;
52 dfs(0,m);
53 writeln(f[0,m]);
54 end.