给定需要保留的树枝数量,求出最多能留住多少苹果。
分析:先建一棵树,保留每个节点的左右子节点。然后用递归进行树形dp。
f[i,j]表示以节点i为根的树保留j个树枝最多能留住多少个苹果。
f[i,j]=max(f[lson,j-1]+w[i,lson],f[rson,j-1]+w[i,rson],f[lson,k]+f[rson,j-k-2]+w[i,lson]+w[i,rson]){0<=k<=j-2}。
代码:
var n,m,x,y,z,i:longint; ld,rd,l,r:array[1..100] of longint; v:array[1..100] of boolean; a,b:array[1..100,0..100] of longint; f:array[1..100,0..100] of longint; function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end; procedure dfs(x:longint); var i:longint; begin v[x]:=false; for i:=1 to a[x,0] do if v[a[x,i]] then begin if l[x]=0 then begin l[x]:=a[x,i]; ld[x]:=b[x,i]; end else begin r[x]:=a[x,i]; rd[x]:=b[x,i]; end; dfs(a[x,i]); end; end; procedure dp(x:longint); var i,j:longint; begin if l[x]=0 then exit; dp(l[x]); dp(r[x]); for i:=1 to m do begin f[x,i]:=max(f[l[x],i-1]+ld[x],f[r[x],i-1]+rd[x]); for j:=0 to i-2 do f[x,i]:=max(f[x,i],f[l[x],j]+f[r[x],i-2-j]+ld[x]+rd[x]); end; end; begin readln(n,m); for i:=1 to n-1 do begin readln(x,y,z); inc(a[x,0]); a[x,a[x,0]]:=y; b[x,a[x,0]]:=z; inc(a[y,0]); a[y,a[y,0]]:=x; b[y,a[y,0]]:=z; end; fillchar(v,sizeof(v),true); dfs(1); dp(1); writeln(f[1,m]); end.