【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 ...