Sample Input
4 1 0.5
2 3 1 3
10.0 10.0 10.0 10.0
Sample Output
30.00
推荐题解:http://blog.csdn.net/whjpji/article/details/7593329
这个题解比较详细,代码上还有注释,比较容易懂
里面有题目讲解
首先我们先算出R(1)的公式,就是(d为深度,根的深度为0,len为环的长度)
这个怎么算呢
首先如果这个是树的话,我们就知道
R(1)等于这个式子的上面那一部分,但是1还有后继,所以有一个环
我们把1拆成两个点,一个做根,一个做叶子
于是R(1)=
n
sssssssssss
i
g ci*k^di + R(1)*k^len
m
aaaaaaaaaaa
i=2
然后我们可以证明如果修改后继,一定是修改为1(因为修改为1,可以最大限度的减小深度和环的长度,这个比较一下就行了)
然后是树形dp,因为有环所以我们先去环,就是枚举环的长度,把那个断点的后继设为1,这样就把分母固定了,我们要做的就是让分子越大越好
dp[i][j][d]表示以i为根的子树,修改j次,i与根的距离为d的最大贡献
上面就是i不修改后继的,下面就是i修改后继的
然后用01背包解决转移(注意,修改的话,c>0才行)
1 const 2 maxn=62; 3 var 4 f,g:array[0..maxn,0..maxn,0..maxn]of double; 5 c,ff,kk:array[0..maxn]of double; 6 pre:array[0..maxn]of longint; 7 ans:double; 8 n,m:longint; 9 10 procedure init; 11 var 12 i:longint; 13 begin 14 read(n,m,kk[1]); 15 for i:=2 to n do 16 kk[i]:=kk[i-1]*kk[1]; 17 for i:=1 to n do 18 read(pre[i]); 19 for i:=1 to n do 20 read(c[i]); 21 end; 22 23 function min(x,y:double):double; 24 begin 25 if x<y then exit(x); 26 exit(y); 27 end; 28 29 function max(x,y:double):double; 30 begin 31 if x>y then exit(x); 32 exit(y); 33 end; 34 35 function min(x,y:longint):longint; 36 begin 37 if x<y then exit(x); 38 exit(y); 39 end; 40 41 procedure dp(u,d:longint); 42 var 43 i,j,k,dd:longint; 44 begin 45 for i:=2 to n do 46 if pre[i]=u then dp(i,d+1); 47 for dd:=min(2,d) to d do 48 begin 49 fillchar(ff,sizeof(ff),0); 50 for i:=2 to n do 51 if pre[i]=u then 52 for j:=m downto 0 do 53 for k:=j downto 0 do 54 ff[j]:=max(ff[j],ff[k]+g[i,j-k,dd]); 55 for j:=0 to m do 56 f[u,j,dd]:=ff[j]+c[u]*kk[dd]; 57 end; 58 if d>1 then 59 begin 60 fillchar(ff,sizeof(ff),0); 61 for i:=2 to n do 62 if pre[i]=u then 63 for j:=m downto 0 do 64 for k:=j downto 0 do 65 ff[j]:=max(ff[j],ff[k]+g[i,j-k,1]); 66 for j:=1 to m do 67 f[u,j,1]:=ff[j-1]+c[u]*kk[1]; 68 end; 69 for j:=0 to m do 70 for dd:=0 to d-1 do 71 g[u,j,dd]:=max(f[u,j,dd+1],f[u,j,1]); 72 end; 73 74 procedure work; 75 var 76 i,j,k,l,len,tmp:longint; 77 now:double; 78 begin 79 i:=pre[1]; 80 len:=2; 81 while i<>1 do 82 begin 83 fillchar(f,sizeof(f),0); 84 fillchar(g,sizeof(g),0); 85 tmp:=pre[i]; 86 pre[i]:=1; 87 now:=0; 88 for j:=2 to n do 89 if pre[j]=1 then dp(j,1); 90 fillchar(ff,sizeof(ff),0); 91 for j:=2 to n do 92 if pre[j]=1 then 93 for k:=m downto 0 do 94 for l:=k downto 0 do 95 ff[k]:=max(ff[k],ff[l]+f[j,k-l,1]); 96 for j:=0 to m-1 do 97 now:=max(now,ff[j]); 98 if tmp=1 then now:=max(now,ff[m]); 99 ans:=max(ans,(now+c[1])/(1-kk[len])); 100 pre[i]:=tmp; 101 i:=pre[i]; 102 inc(len); 103 end; 104 writeln(ans:0:2); 105 end; 106 107 begin 108 init; 109 work; 110 end.