二叉蘋果樹 樹形DP

2021-07-11 16:21:48 字數 2995 閱讀 7952

題意/description:

有一棵蘋果樹,如果樹枝有分叉,一定是分2叉(就是說沒有只有1個兒子的結點) 

這棵樹共有n個結點(葉子點或者樹枝分叉點),編號為1-n,樹根編號一定是1。 

我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 

2 5 

\ / 

3 4 

\ / 

1 現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋果。

給定需要保留的樹枝數量,求出最多能留住多少蘋果。 

讀入

/input

第1行2個數,n和q。

n表示在樹列舉的點數。q表示應保留的分支數量。

下來n - 1行中包含分支的描述。每個描述包括三個整數用空格分開的。它們的前兩個由它的結束點定義分支。第三個數字上定義這個分支蘋果的數量。你可以假設沒有分支包含超過30000蘋果。

輸出

/output

乙個數,最多能留住的蘋果的數量。

題解

/solution

這個題目都講到了二叉了,很容易的想到樹型dp。不講廢話,進入話題。

如果只有乙個容量,取左右兩邊最大值。

f[t,x]:=max(g[t,l[t]],g[t,r[t]]);

如果大於乙個容量,先設左右兩邊都被分配。

f[t,x]:=max(f[t,x],f[l[t],i]+f[r[t],x-2-i]);

然後只取左邊或只取右邊。

f[t,x]:=max(f[t,x],f[l[t],x-1]+g[t,l[t]]); 或 f[t,x]:=max(f[t,x],f[r[t],x-1]+g[t,r[t]]);

**

/code:

var

n,q,o:longint;

a,g,f:array [0..101,0..101] of longint;

v:array [0..101] of boolean;

l,r,du:array [0..101] of longint;

function max(t,k:longint):longint;

begin

if t>k then exit(t);

exit(k);

end;

procedure tree(x:longint);

var i:longint;

begin

if x=0 then exit;

v[x]:=true;

for i:=1 to a[x,0] do

if not v[a[x,i]] then

if l[x]=0 then l[x]:=a[x,i]

else r[x]:=a[x,i];

tree(l[x]);

tree(r[x]);

end;

procedure main(t,x:longint);

var i:longint;

begin

if (x=0) or (t=0) then

begin

f[t,x]:=0;

exit;

end;

if f[t,x]>0 then exit;

if x=1 then

begin

f[t,x]:=max(g[t,l[t]],g[t,r[t]]);

exit;

end;

for i:=0 to x-2 do

begin

main(l[t],i);

main(r[t],x-2-i);

f[t,x]:=max(f[t,x],f[l[t],i]+f[r[t],x-2-i]);

end;

f[t,x]:=f[t,x]+g[t,l[t]]+g[t,r[t]];

main(l[t],x-1);

f[t,x]:=max(f[t,x],f[l[t],x-1]+g[t,l[t]]);

main(r[t],x-1);

f[t,x]:=max(f[t,x],f[r[t],x-1]+g[t,r[t]]);

end;

procedure init;

var i,x,y,z:longint;

begin

readln(n,q);

for i:=1 to n-1 do

begin

readln(x,y,z);

g[x,y]:=z; g[y,x]:=z;

inc(a[x,0]); a[x,a[x,0]]:=y;

inc(a[y,0]); a[y,a[y,0]]:=x;

end;

o:=1;

for i:=1 to n do

if a[i,0]=2 then

begin

o:=i;

break;

end;

end;

begin

init;

tree(o);

main(o,q);

write(f[o,q]);

end.

樹形DP 二叉蘋果樹

有一棵二叉蘋果樹,如果樹枝有分叉,一定是分兩叉,即沒有只有乙個兒子的節點。這棵樹共 n 個節點,編號為 1 至 n,樹根編號一定為 1。我們用一根樹枝兩端連線的節點編號描述一根樹枝的位置。一棵蘋果樹的樹枝太多了,需要剪枝。但是一些樹枝上長有蘋果,給定需要保留的樹枝數量,求最多能留住多少蘋果。這裡的保...

二叉蘋果樹(樹形DP)

原題 顯然我們考慮這道題目可以很蠢的寫乙個dp對吧。考慮 dp i,j 表示以i為根,保留j個節點的最大蘋果數。然後就可以樹形dp的寫了。include include include include include include include define ll long long defin...

二叉蘋果樹 樹形dp

p2015 二叉蘋果樹 洛谷 電腦科學教育新生態 luogu.com.cn 嗚嗚嗚嗚,真的是一道厲害題 至少對目前的我來說 研究了乙個小時。首先,因為我們不知道一對座標中,誰是父親,誰是兒子,所以用無向圖把二者連起來,但最後dfs的時候還是只用其中乙個。狀態表示 i的子樹上保留j條邊時蘋果的最大值 ...