置換,迴圈,遞推(排列統計,UVA 11077)

2021-07-24 21:42:06 字數 889 閱讀 8901

把排列看成置換,再把置換寫成迴圈乘積。觀察迴圈,設某個迴圈中有c個元素,那麼這些元素在排列中一共要交換c-1次才能到對應的位子,設有x個迴圈,那麼需要交換的次數便是c1-1+c2-1+...+cx-1=n-x,這是乙個跟元素個數以及迴圈個數有關的量。

定義狀態f(i,j),表示變成(1,2,..,i)需要j次交換的排列個數。

那麼容易得到狀態轉移方程f(i,j)=f(i-1,j)+f(i-1,j-1)*(i-1)。意思是第i個數可以單獨成乙個迴圈,也可以插入前面任意乙個迴圈的任意乙個位子。

有些難理解,所以解釋一波。

第i個數可以單獨成乙個迴圈:那麼元素個數為n+1,迴圈個數為x+1,需要交換的次數=(n+1)-(x+1)=n-x所以沒變。

所以才由f(i-1,j)轉移過來。

也可以插入前面任意乙個迴圈的任意乙個位子:元素個數n+1,迴圈個數x不變,所以需要交換的次數=(n+1)-x=n-x+1所以多了1。所以從f(i-1,j-1)轉移過來。因為可以插入任何元素的前面,而f(i-1,j-1)一共有

(i-1)個元素,所以答案就是f(i-1,j-1)*(i-1)。

易得j一定小於i(迴圈至少有1個),否則f[i][j]=0。邊界為f[1][0]=1。

竟然卡unsigned long long。

其實自己先前多試幾個大資料就好了。

** #include#define maxn 25

using namespace std;

typedef unsigned long long ll;

ll f[maxn][maxn];

ll n,k;

void init()

{ f[1][0]=1;

for(ll i=2;i<=21;i++)

for(ll j=0;j

HOJ 10182 置換排列

置換排列 time limit 1000ms,special time limit 2500ms,memory limit 32768kb total submit users 1290,accepted users 1137 problem 10182 no special judgement p...

錯位排列遞推公式推導

全錯位排列 即被著名數學家尤拉 leonhard euler,1707 1783 稱為組合數論的乙個妙題的 裝錯信封問題 裝錯信封問題 是由當時最有名的數學家約翰 伯努利 johann bernoulli,1667 1748 的兒子丹尼爾 伯努利 danidbernoulli,1700 1782 提...

HDU 2065 遞推 迴圈節

題義 規定這樣的乙個序列,只由a,b,c,d四種字元組成,並且a和c的個數都為偶數個,現在問乙個長度為n的序列,有多少種構成方式能夠使長度為n的串滿足這些要求。解法 對於任意長度的乙個串,我們設定三個狀態f i 0 表示滿足要求的合法串,f i 1 表示a和c只有乙個字元不滿足的非法串,f i 2 ...