題目大意:求乙個聯通點集點權和≤
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 現在這顆樹枝條太多了...