題解 BZOJ2169 連邊

2022-05-07 22:30:14 字數 1230 閱讀 9432

看到資料範圍很容易想到 dp 方程式

設 \(f[i][j]\) 代表已經連了 \(i\) 條邊, 還有 \(j\) 個奇數點, 並且方案全部合法的方案數

那麼有\[\displaystyle \beginf[i][j] = &f[i - 1][j + 2]*\binom\\+&f[i - 1][j - 2]*\binom\\+&f[i - 1][j]*(n-j)*j\end

\]分別代表連兩個奇數點, 兩個偶數點, 乙個奇數點乙個偶數點

注意一下邊界即可

但是問題在這裡, 這次連的邊有可能與之前新連的某一條邊重合, 這樣方案就不合法了, 我們可以強制這兩條邊是先後連的

因為我們求的是連邊的方案, 沒有順序, 所以這樣不會對答案造成影響

即\[\displaystyle f[i][j] -= f[i - 2][j]*(\binom-(i-2))

\]這兩條邊先後連, 所以在這之前已經連了 \(i - 2\) 條邊, 這條邊可能連在任意兩個點中間, 但是不能與之前的那 \(i - 2\) 條邊相重複了, 因為實際上我們是把 dp 的兩步轉移並做了一步, 若與之前的 \(i - 2\) 條邊重合了, 那麼在第一次轉移後的 \(f\) 就不符合全部合法的定義了

除此之外, 每次轉移完之後都要除以 \(i\) , 因為方案是無序的

舉乙個例子, 比如說上次我們連邊的方案分別是 \((1, 2)\) , \((2, 3)\) , \((1, 3)\)

若這次我們分別連上 \(3\) , \(1\) , \(2\) , 那麼三種方案最終都是 \((1, 2, 3)\) , 重複了

所以要除去 \(i\)

#include #include #include #include const int n = 1005;

const int mod = 10007;

using namespace std;

int n, m, k, d[n], c[n][n], f[n][n], inv[n], cnt;

template < typename t >

inline t read()

while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();

return x * w; }

int main()

printf("%d\n", f[k][0]);

return 0;

}

bzoj 2169 連邊 DP 容斥

題目 就和這篇部落格說的一樣 注意每次是 i 而不是 i 因為 i 1 時也已經去了重,現在就是對於新加一條邊的多種方式帶來一種局面去重,從每一種局面看,新加的邊可以是任意一條,所以 i。如下 include include include include using namespace std t...

退役四連測題解(一)

有q只猴子要從第一棵樹到第n棵樹去,第i只猴子一次跳躍的最遠距離為ki。如果它在第x棵樹,那它最遠可以跳到第x ki棵樹。如果第j棵樹的高度比第i棵樹高或相等,那麼它從第i棵樹直接跳到第j棵樹,它的勞累值會增加1。所有猴子一開始在第一棵樹,請問每只猴子要跳到第n棵樹花費的勞累值最小。第一行乙個整數n...

題解 BZOJ 4717 裝備

傳送門 由於這道題是許可權題,所以題面我也放在這裡了 我不是許可權狗 題目背景 小q最近喜歡上了一款遊戲,名為 艦隊connection 在遊戲中,小q指揮強大的艦隊南征北戰,從而成為了一名dalao。在遊戲中,不僅船隻能力很重要,搭配合適的裝備更是如虎添翼。小q潛心研究配裝三十年,終於 把裝備湊齊...