洛谷P2015 二叉蘋果樹 樹形DP

2021-10-09 04:14:27 字數 1805 閱讀 9603

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

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

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

2

5 \ /34

\ /1

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

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

第1行2個數,n和q(1<=q<= n,1

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

521

3114

102320

3520

21
解題思路

這是一道樹形dp的板子題。

f[i][j]表示以i為根節點的子樹,保留j條樹枝時的,保留的最大蘋果數。

(這道題有乙個隱含的條件,當某條邊被保留下來時,從根節點到這條邊的路徑上的所有邊也都必須保留下來)那麼狀態轉移方程為:

f [d

ep][

j]=m

ax(f

[dep

][j]

,f[s

on][

k]+f

[dep

][j−

k−1]

+a[s

on][

dep]

);

f[dep][j]=max(f[dep][j],f[son][k]+f[dep][j−k−1]+a[son][dep]);

f[dep]

[j]=

max(

f[de

p][j

],f[

son]

[k]+

f[de

p][j

−k−1

]+a[

son]

[dep

]);為什麼是f[d

ep][

i−k−

1]

f[dep][i−k−1]

f[dep]

[i−k

−1]而不是f[d

ep][

i−k]

f[dep][i−k]

f[dep]

[i−k

]?因為保留一條邊必須保留從根節點到這條邊路徑上的所有邊,那麼如果你想從u的子節點v的子樹上留邊的話,也要留下u,v之間的連邊。

另外,我的連線方式有點特別,用的是鄰接表連線點,用鄰接矩陣存邊權。其實只用鄰接矩陣就可以了,比較方便。

#include

#include

#include

#include

using

namespace std;

int n,q,x,y,v,tot,h[

101]

,e[101

],f[

101]

[101

],s[

101]

[101];

struct node

a[220];

void

add(

int x,

int y)

; h[x]

=tot;

}voiddp(

int k)}}

}int

main()

dp(1)

; cout<[q];

//q是要保留的樹枝數量

return0;

}

洛谷 P2015 二叉蘋果樹 樹形dp

有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋...

洛谷P2015 二叉蘋果樹(樹形dp)

有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 3 4 1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝上長有蘋...

洛谷P2015 二叉蘋果樹 樹形dp)

題目描述 有一棵蘋果樹,如果樹枝有分叉,一定是分2叉 就是說沒有只有1個兒子的結點 這棵樹共有n個結點 葉子點或者樹枝分叉點 編號為1 n,樹根編號一定是1。我們用一根樹枝兩端連線的結點的編號來描述一根樹枝的位置。下面是一顆有4個樹枝的樹 2 5 34 1現在這顆樹枝條太多了,需要剪枝。但是一些樹枝...