嘟嘟嘟
從今天開始搞一搞組合計數!
先學乙個錯排公式。
所謂的錯排就是乙個排列,滿足對於任意的\(i\),有\(a[i] \neq i\)。
這東西是可以遞推求的。
令\(d[i]\)表示長度為\(n\)的排列的錯排數。我們假設\(d[n - 1]\)已經求出來,現在考慮第\(n\)個。
首先第乙個肯定要和其中任意第\(i\)個\((1 \leqslant i \leqslant n - 1)\)交換,所以這就有\(n - 1\)種可能。但至於第\(i\)個數放哪兒,就得分類討論。
1.第\(i\)個數就放在第\(n\)位上,那麼方案數就是剩下\(n - 2\)個數的錯排數\(d[n - 2]\)。
2.第\(i\)個數也可能不在第\(n\)位上。這時候,我們把第\(i\)個數看成新的「第\(n\)個數」,那麼這就變成了乙個子問題,就是除了原來的那個「第\(n\)個數」的剩下\(n - 1\)個數的錯排數,即\(d[n - 1]\)。
綜上,得到遞推公式\(d[n] = (n - 1) * (d[n - 1] + d[n - 2])\)。
如果覺得我這個講的太撈,推薦這個大佬的部落格:徹底搞懂錯排公式
對於這道題,答案就是\(c_ ^ * d[n - m]\)啦。
#include#include#include#include#include#include#include#include#include#include#includeusing namespace std;
#define enter puts("")
#define space putchar(' ')
#define mem(a, x) memset(a, x, sizeof(a))
#define in inline
typedef long long ll;
typedef double db;
const int inf = 0x3f3f3f3f;
const db eps = 1e-8;
const int maxn = 1e6 + 5;
const ll mod = 1e9 + 7;
in ll read()
in void write(ll x)
in void myfile()
int n, m;
ll fac[maxn], inv[maxn], d[maxn];
in ll c(int n, int m)
in ll inc(ll a, ll b)
in ll quickpow(ll a, ll b)
in void init()
int main()
return 0;
}
SDOI 2016 排列計數
題目鏈結 演算法 有m個數在原來的位置上,說明有 n m 個數不再原來的位置上 那麼,我們可以選出 n m 個數,使這 n m 個數都不在原來的位置上,再讓剩下的m個數都在原來的位置上 錯位排列遞推公式 f 1 0 f 2 1 f n n 1 f n 1 f n 2 n 2 因此,答案為c n,n ...
SDOI2016 排列計數
求有多少種長度為 n 的序列 a,滿足以下條件 1 n 這 n 個數在序列中各出現了一次 若第 i 個數 a i 的值為 i,則稱 i 是穩定的。序列恰好有 m 個數是穩定的 滿足條件的序列可能很多,序列數對 10 9 7 取模。第一行乙個數 t,表示有 t 組資料。接下來 t 行,每行兩個整數 n...
SDOI2016 排列計數
這不是錯排嗎?誒,我怎麼一眼就看出來了?誒,我怎麼打不來錯排?誒,我怎麼躺地上了?洛谷 m 個數字是對應的位置那麼就有 c n m 種情況,剩下的數字只需要求出錯排數,即求出 d n m 就搞定了 那麼怎麼求錯排呢?前往部落格食用 錯排組合數就不用多說了吧,配合逆元求解 答案就是 c n m d n...