收集果子(樹形dp)

2021-09-27 11:49:07 字數 1277 閱讀 6732

題意:給你一棵樹,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,你就知道了 ...