樹形揹包 蘋果樹

2021-09-18 03:55:02 字數 1718 閱讀 9402

題目大意:求乙個聯通點集點權和≤

m\leq m

≤m的最大點的個數。

這道題是乙個樹形揹包問題,以點的個數為體積,以體積為價值;然後我們只要找到體積≤

m\le m

≤m的最大點數即可。

我們設f[i

][j]

f[i][j]

f[i][j

]表示以i

ii為根的子樹中,一定選第i

ii個點且選了j

jj個點的最小花費。

若當前節點為x

xx,乙個子節點為y

yy,則有狀態轉移方程:f[x

][i+

j]=m

in(f

[y][

j]+f

[x][

i]

)f[x][i+j]\ =\ min(f[y][j]+f[x][i])

f[x][i

+j]=

min(

f[y]

[j]+

f[x]

[i])

如果你講i的範圍定為1≤i

≤min

(siz

e[x]

,m

)1\le i\le min(size[x],m)

1≤i≤mi

n(si

ze[x

],m)

,那麼會超時。

由於題目中給定每乙個w

iw_i

wi​都不相同,設1+2

+...

+m≤m

1+2+...+m\leq m

1+2+..

.+m≤

m,那麼i的取值範圍就是1≤i

≤min

(siz

e[x]

,m

)1\le i\le min(size[x],m)

1≤i≤mi

n(si

ze[x

],m)

.同理,j

jj的取值範圍是:1≤j

≤min

(m,s

ize[

y]

)1\le j\le min(m,size[y])

1≤j≤mi

n(m,

size

[y])

。**如下:

#include

using

namespace std;

const

int n =

200000

;int n,m,m;

int ans =0;

int size[n]

;int f[n]

[500];

vector <

int> a[n]

;voiddp(

int x,

int fa)

for(

int i=m;i>ans;

--i)

if(f[x]

[i]<=m)

}int

main

(void)}

for(

int i=

1;i<=n;

++i)

for(

int i=

1;i++i)dp(

1,0)

;printf

("%d"

,ans)

;return0;

}

樹形dp TT的蘋果樹

在大家的三連助攻下,tt 一舉獲得了超級多的貓咪,因此決定開一間貓咖,將快樂與大家一同分享。並且在開業的那一天,為了紀念這個日子,tt 在貓咖門口種了一棵蘋果樹。一年後,蘋果熟了,到了該摘蘋果的日子了。已知樹上共有 n 個節點,每個節點對應乙個快樂值為 w i 的蘋果,為了可持續發展,tt 要求摘了...

SDOI2017 蘋果樹(揹包dp)

題目鏈結 樹上依賴多重揹包,允許從根出發的一條鏈中每個點上的乙個物品免費,求最大價值。揹包神仙題 首先都能想到的就是列舉某個節點,這個節點到根上的所有節點使用一次免費的機會,那麼整棵樹就被分成了三部分 1.這條鏈上所有點剩餘物品數量為ai 1a i 1 ai 1 2.這條鏈左邊所有點不變。3.這條鏈...

二叉蘋果樹 樹形DP

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