参考论文《对一类动态规划问题的研究》
《多角度思考创造性思维——运用树型动态规划解题的思路和方法探析》
这类动态规划的特点就是当前的决策会影响未来“行动”的费用,而我们并不能记录每个的所有决策
这时候我们就考虑在当前状态对未来状态预估,从而提前计算当前决策对未来影响的费用
下面的几道题目都很好,并且都能在这两篇论文中找到详细的题解,这里就贴代码不再赘述了
bzoj1812
不错的树dp,处理x为根子树的时候,我们预估x的某个祖先有伐木场时子树内的运费
详见《多角度思考创造性思维——运用树型动态规划解题的思路和方法探析》
1 const inf=2147483647; 2 type node=record 3 po,next,num:longint; 4 end; 5 6 var e:array[0..210] of node; 7 w,fa,p,d,g:array[0..110] of longint; 8 f:array[0..110,0..110,0..110] of longint; 9 i,j,k,len,x,y,n,m:longint; 10 11 procedure add(x,y,z:longint); 12 begin 13 inc(len); 14 e[len].po:=y; 15 e[len].num:=z; 16 e[len].next:=p[x]; 17 p[x]:=len; 18 end; 19 20 function min(a,b:longint):longint; 21 begin 22 if a>b then exit(b) else exit(a); 23 end; 24 25 procedure dfs(x:longint); 26 var i,y,z,mi:longint; 27 begin 28 if p[x]=0 then 29 begin 30 i:=fa[x]; 31 while i>-1 do 32 begin 33 f[x,i,0]:=(d[x]-d[i])*w[x]; 34 i:=fa[i]; 35 end; 36 f[x,x,1]:=0; 37 exit; 38 end; 39 i:=p[x]; 40 while i<>0 do 41 begin 42 y:=e[i].po; 43 d[y]:=d[x]+e[i].num; 44 dfs(y); 45 i:=e[i].next; 46 end; 47 i:=p[x]; 48 while i<>0 do 49 begin 50 y:=e[i].po; 51 z:=x; 52 while z>-1 do 53 begin 54 for j:=m downto 0 do 55 begin 56 mi:=inf; 57 for k:=0 to j do 58 mi:=min(mi,f[x,z,k]+f[y,z,j-k]); 59 f[x,z,j]:=mi; 60 end; 61 z:=fa[z]; 62 end; 63 i:=e[i].next; 64 end; 65 z:=fa[x]; 66 while z>-1 do 67 begin 68 for i:=0 to m do 69 if f[x,z,i]<inf then f[x,z,i]:=f[x,z,i]+(d[x]-d[z])*w[x]; 70 z:=fa[z]; 71 end; 72 fillchar(g,sizeof(g),0); 73 i:=p[x]; 74 while i<>0 do 75 begin 76 y:=e[i].po; 77 for j:=m downto 0 do 78 begin 79 mi:=inf; 80 for k:=1 to j do 81 mi:=min(mi,g[k]+f[y,x,j-k]); 82 g[j]:=mi; 83 end; 84 i:=e[i].next; 85 end; 86 z:=x; 87 while z>-1 do 88 begin 89 for i:=0 to m do 90 f[x,z,i]:=min(f[x,z,i],g[i]); 91 z:=fa[z]; 92 end; 93 end; 94 95 begin 96 readln(n,m); 97 for i:=1 to n do 98 begin 99 readln(w[i],fa[i],y); 100 add(fa[i],i,y); 101 end; 102 fa[0]:=-1; 103 dfs(0); 104 writeln(f[0,0,m]); 105 end.