數學 數論 康托展開與逆康托展開

2022-09-15 06:09:08 字數 1026 閱讀 9997

康托展開

可以理解為把乙個全排列對映到乙個數上面,因為全排列如果按照從小到大或者從大到小,肯定是有乙個確定的序列的。

一般是從小到大的序列個數。我們就是要求出這個序列的位置。,想法很簡答,就是求出前面比他小的個數就可以了。

理解為乙個每位都是階乘進製的數轉化為10進製的數。思路如下:

先準備求每一位的階乘,然後從高位開始統計後面有多少個數比他小記錄這個個位數,然後乘以後面個數的階乘,再把它累加起來。

x[i]表示第i位後面比他小的個數,那麼∑1

nx[i

]∗fa

c[n−

i]1∑

n​x[

i]∗f

ac[n

−i]這樣就能求出比他小的有多少個了,也能求出他是第幾個序列。

//求出階乘

void

init()

}int

kangtuo

(int n,

char a)

return sum+1;

}

逆康托展開

相當於知道序列位置求這個位置的數。

想法也很簡單,因為對於每位的fac[n-i]都比後面說有的和都大,所以用pos/fac[n-1]求得的就是x[i],同理pos%fac[n-i]就是後面的和。

我們維護乙個序列st始終按照從小到大排列,那麼已知某位置的x[i],那麼這個位置的數就是st[x[i]+1]。

void

init()

}void

reverse_kangtuo

(int n,

int k,

char s)

;--k;

for(i=

0; i) s[i]

='0'

+j; vst[j]=1

; k %

= fac[n-i-1]

;}}

數學 數論 康托展開與逆康托展開

康托展開 可以理解為把乙個全排列對映到乙個數上面,因為全排列如果按照從小到大或者從大到小,肯定是有乙個確定的序列的。一般是從小到大的序列個數。我們就是要求出這個序列的位置。想法很簡答,就是求出前面比他小的個數就可以了。理解為乙個每位都是階乘進製的數轉化為10進製的數。思路如下 先準備求每一位的階乘,...

數學 康托展開 康托逆展開

7.15 康托展開,就是把全排列轉化為唯一對應自然數的演算法。它可以建立1 n的全排列與 1,n 之間的自然數的雙向對映。1 康托展開 儘管我並不清楚康托展開的原理何在,這個演算法的過程還是比較好記的。正確性之後有機會詢問下學長。如果從1開始給全排列的排名從大到小編號的話 從0開始也可,建立的是與 ...

(數論十一)康托展開與逆康托展開

一.引出康托展開 動態規劃題有一類分支叫狀壓dp,意思就是把狀態壓縮為乙個二進位制陣列,然後轉為十進位制數儲存。一般n的大小不會超過20,因為20個狀態的組合就有2 20,也就是1e6種可能。對於一些題目,緊緊利用狀態壓縮,會發現狀態的組合數遠遠超過1e6的範圍,那時候我們沒有辦法在1s內遍歷出來,...