題意:給你一棵樹,1為根節點,每個節點有果子數,每個節點的權值為其子樹果子的和。問多少種刪邊的方式,使得1節點的權值為k。
思路:組成k的種類數??不就是多少種方法組成某個面值嗎,可以想到是樹上揹包。定義f(i,j)為遞迴到第i個節點收集了j個果子的方案數。那麼有兩種子狀態:(1)把(u,v)邊斷了,那麼結果乘上p(size(u)-1) x f(u,i)。p(i)代表2的i次方。(2)加上以v節點代表的子樹,那麼結果就是f(u,i-j) x f(v,j).
但是極限資料拉到了1000,這個n^3的演算法好理解,但是題解裡面的n方演算法還是沒有理解完全(而且沒法評測┭┮﹏┭┮)。
#include
#include
#include
using
namespace std;
typedef
long
long ll;
const ll mod =
1e9+7;
ll a[
1005];
ll f[
1005][
1005
],g[
1005
],p[
105]
,size[
1005];
ll head[
1005
],nex[
1005
],to[
1005
],tot;
ll n,k;
void
add(ll x,ll y)
void
dfs(ll u,ll fa)
//n^3
}for
(ll i =
0;i <= k;i++)}
}void
dfs2
(ll u,ll fa)
//n^2}}
intmain()
for(ll i =
1;i <= n -
1;i++
) p[0]
=1;for
(ll i =
1;i <= n;i++
)p[i]
= p[i -1]
*2% mod;
dfs(1,
-1);
printf
("%lld\n"
,f[1
][k]);
return0;
}
(偶然看到的一道題,所以沒有評測,原帖 1272 摘果子(樹形dp,dfs
description 樹有n個節點,樹根為1號節點,這顆果樹上有m個節點長出果實 根節點1有可能長出果實 小明要從節點1出發採集這些果實,從乙個節點爬到相鄰的另乙個節點所需要的時間為1,採集果實不需要時間,問如果要採集這m個果實,從節點1出發,並且最後需要回到節點1,最少需要多少的時間。節點編號1...
nssl1196 摘果子 樹形依賴揹包,dp
有n個東西,每個東西有價值和 然後要求乙個 上限,和除了第乙個東西以外都有乙個買這個之前必須要買的東西。求最大價值 我們考慮之前的樹形揹包 然後發現時間複雜度o n 3 o n 3 o n3 之後我們考慮乙個方法 之前是將子節點合併起來所以時間會很久,可是我們可以將乙個子節點處理好,然後直接仍給它的...
C Garland (樹形DP 子樹計數問題)
又攻克一道樹形dp題,首先子樹計數問題,感覺都是先自下而上跑一遍dfs,然後根據題意然後抉擇得套路。一顆有根樹,分成三棵子樹,保證點權和相互相等。分析 子樹滿足ans 3,並且ans 3 0加入就可以了,滿足兩個點或者以上,就是行 為啥說2以上 這裡就是我得wa得點,可以所有得點值為0,你就知道了 ...