樹形揹包優化 updating

2021-10-24 13:38:11 字數 1507 閱讀 2158

自從上次模擬賽後,我決定隔一段時間整理一些揹包優化,可能毫無順序

1.d fs

dfsdf

s的時候儲存鏈的資訊

一道模擬賽題:給定一棵樹,有n

nn各節點,每個節點都有乙個非負權值,對於每條邊,你有0.5

0.50.

5的概率斷掉這條邊,求以1

11為根遍歷的數的權值之和為k

kk的概率(答案對998244353

998244353

998244

353取模)

1

<=n

,k

<

=5000

1 <= n,k <= 5000

1<=n

,k<=5

000直接設dp[

i][j

]dp[i][j]

dp[i][

j]代表以i

ii為根的子樹權值之和為k

kk的概率,這樣dpdp

dp的複雜度是o(n

3)

o(n^3)

o(n3

)那麼怎麼優化呢,我們只需設dp[

i][j

]dp[i][j]

dp[i][

j]為遍歷完以i

ii為根的子樹,權值之和為k

kk的概率

注意,這兩個狀態的不同是第二個狀態也記錄了從1

11走到i

ii的情況(因為遍歷是從1

11開始的)

具體轉移看**即可

#include

#include

#include

#include

using

namespace std;

#define int long long

const

int maxn =

5000

, p =

499122177

, mod =

998244353

;struct whead[maxn + maxn +10]

;int a[maxn +10]

, val[maxn +10]

, size[maxn +10]

, dp[maxn +10]

[maxn+10]

, n, k;

inline

void

add(

int x,

int y,

int i)

inline

intread()

void

dfs(

int x,

int fa)

}signed

main()

dp[1]

[val[1]

]=1;

dfs(1,

0); cout << dp[1]

[k]<< endl;

return0;

}

樹形依賴揹包

問題大意 給出一棵樹,根節點為1,每個點有毒素和收穫。要求毒素不超過給定值的情況下使收穫最大。乙個點的父親節點被選取後這個點才能被選取。首先弄出dfs序,也記錄下每個點其子樹及自身的大小。每個點都能夠被選或不選,如果選了才會考慮它子樹。設f i j 表示dfs序上第i位上的點在其子樹及自身上選取了毒...

樹形揹包總結

目錄 2 有物品大小 3 物品大小為1,有k的限制。二 dfs序上dp 例題1例題2 例題3總結下 樹形揹包,就是說,在樹上選乙個包含根的連通塊,或揹包存在依賴關係 選父才能選子 或者需要知道每個點的子樹中選了多少 通常,我們有兩種方法 我們設 dp i,j 表示在i的子節點中選j個的狀態。在轉移時...

樹形揹包DP

include using namespace std const int n 310,m n 2 int h n ne m v m idx int w n int dp n n int n,m void add int a,int b void dfs int u for int j m j 0 ...