SDOI2016 排列計數

2022-05-09 10:30:11 字數 1375 閱讀 5008

嘟嘟嘟

從今天開始搞一搞組合計數!

先學乙個錯排公式。

所謂的錯排就是乙個排列,滿足對於任意的\(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...