洛谷 2015 二叉蘋果樹

2022-04-28 20:15:10 字數 1800 閱讀 2282

luogu

sol

首先需要根據題目條件把蘋果樹建出來

容易想到f[i][j]表示以i結點為根的蘋果樹上保留j個結點所能保留的最大蘋果樹

需要注意的是f[i][j]包括i結點(根)與它的父親聯結的枝條上的蘋果

轉移的話就列舉i的第乙個子結點保留的結點數k,那麼另乙個子結點保留的就是j-k-1

這題的轉移還是很簡單的,因為它是二叉的,只有二叉鴨

如果是多叉呢? 那不就和選課一樣了嘛,是乙個樹形揹包問題 樹形dp+分組揹包

和選課略有不同的是蘋果在邊上,而課程在結點上

code

(是很久以前的code,好像和現在風格不太一樣qwq,大概是因為以前不壓行??)

1 #include2 #include3 #include4

using

namespace

std;

5int dp[110][110];6

int a[110];7

int map[110][110];8

int lc[110],rc[110];9

intn,q;

10void build(int

now)

1122}23

for(int i=1;i<=n;i++)

2433}34

}35int dp(int now,int

data)

3644

return

dp[now][data];45}

46int

main()

4755 build(1

);56 cout<1

,q);

57return0;

58 }

沒有注釋版 code

1 #include2 #include3 #include4

using

namespace

std;

5int dp[110][110]; //

dp[i][j] 以i為根節點的樹上保留j個節點的最大蘋果數6//

注意dp[i][j]包括根節點和它的父親的邊上的蘋果數7//

保留i個節點包括根節點 也就是說它的孩子結點只能保留i-1個

8int a[110]; //

a[i]節點i與它的父親相連的邊上的蘋果數

9int map[110][110]; //

map[i][j]:i與j連線的邊上的蘋果樹 若無邊則初始化為-1

10int lc[110],rc[110]; //

lc[i]:i的左孩子 rc:右孩子

11int

n,q;

12void build(int now) //

建樹 1324}

25for(int i=1;i<=n;i++)

2635}36

}37int dp(int now,int data) //

以now為根節點的樹上保留data個結點

3846

return

dp[now][data];47}

48int

main()

4957 build(1); //

以1為根結點建樹 其實就是為了記錄每個點的左右孩子以及它與自己父親相連的邊上的結點數

58 cout<1,q); //

樹形dp

59return0;

60 }

詳細注釋版 code

洛谷 2015 二叉蘋果樹

題意就是給你n 1條樹枝,每條樹枝上都帶有一定的蘋果,問最後留下m根樹枝,能擁有的蘋果的最大值,根節點為1,每個節點只有2種情況,有2個兒子,或沒有兒子。這題是乙個很典型的樹形結構,因為節點以邊相連,又為二叉結構,無環。我們這時候從根節點下順,找到最深的兒子,然後一步步開始回溯,以當前回溯到的這個點...

洛谷 P2015 二叉蘋果樹

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

洛谷P2015 二叉蘋果樹

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