JSOI 2018 潛入行動(樹形動態規劃)

2021-08-20 03:32:27 字數 1700 閱讀 5817

【jsoi 2018】潛入行動 求

n n

個節點的樹上大小為

k' role="presentation" style="position: relative;">k

k的覆蓋集個數。本題中乙個被標記的點可以覆蓋所有與之相鄰的點,但是不能覆蓋其本身。 n≤

100000

n

≤100000

,m≤100 m

≤100

dp[ver

][cn

t][0

/1][

0/1]

d p[

ver]

[cnt

][0/

1][0

/1

]表示節點ve

r ver

的子樹中選出cn

t cnt

個節點,其中選了/不選節點ve

r ver

,ver ver

是/否被覆蓋的方案數量。

狀態轉移方程見**。

但是,暴力轉移會超時。

那就加乙個優化:每個節點ve

r ver

的子樹中最多選si

ze[v

er] siz

e[ve

r]

個節點。

算一下siz

e[ve

r]s iz

e[ve

r]

就可以啦。

#include 

const

int maxn = 100005;

const

int maxm = 105;

const

int maxe = 200005;

const

int mod = 1e9+7;

typedef

unsigned

long

long ull;

int n, m, sz[maxn], dp[maxn][maxm][2][2];

int tot, ter[maxe], nxt[maxe], lnk[maxn];

ull cur[maxm][2][2];

inline

void upd(int &a, int b)

inline

int min(const

int &a, const

int &b)

void addedge(int u, int v)

void treedp(int u, int p)

sz[u] += sz[v];}/*

我可以用來 debug 程式!

for (int x = 0; x <= m; x++)

for (int x0 = 0; x0 <= 1; x0++)

for (int x1 = 0; x1 <= 1; x1++)

printf("dp[%d][%d][%d][%d] = %d\n", u, x, x0, x1, dp[u][x][x0][x1]);

*/}int main()

treedp(1, 0);

printf("%d\n", (dp[1][m][0][1] + dp[1][m][1][1]) % mod);

return

0;}

JSOI2018 潛入行動

題目 我好菜啊,嚶嚶嚶 原來本地訪問陣列負下標不會報 re 或者 wa 甚至能跑出正解啊 這道題還是非常呆的 我們發現 k 很小,於是斷定這是乙個樹上揹包 發現在乙個點上安裝控制器並不能控制這個點,可能需要到父親那邊才能控制這個點,於是我們設 dp i j 0 1 0 1 表示在以 i 為根的子樹裡...

JSOI2018 潛入行動

一棵 n n le10 5 個結點的樹,在一些點上安裝 k k le min n,100 個裝置。每個裝置可以控制所有與安裝位置相鄰的結點 不包括本身 每個點可以安裝至多乙個裝置。問有多少種方案恰好用完 k 個裝置,使得所有的結點都被控制。樹形dp。f i j 0 1 0 1 表示以 i 為根的子樹...

JSOI2018 潛入行動

題目鏈結 參考題解 注意題面 在當前節點設定監聽裝置不能監聽到節點本身。那麼節點能否被覆蓋和節點是否設定監聽裝置需要分開設。設 f 表示以第 i 個節點為根的子樹,除了 i 以外的節點都已經被覆蓋,i 號節點有沒有設定監聽裝置 有沒有被覆蓋的方案數。轉移方程 f sum f f f sum f f ...