康托展开

 

公式

X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! 其中,a为整数,ai为当前未出现的数字中是排在第几个(从0开始)。因此0<=ai<i,1<=i<=n。

X便是整个全排列中第X大的数。

用途

显然,n位(0~n-1)全排列后,其康托展开唯一且最大约为n!,因此可以由更小的空间来储存这些排列。由公式可将X逆推出对应的全排列。

 

两种实现

正向展开:

View Code
 1 //value数组存放当前排列   
2 const int fac[]={1,1,2,6,24,120,720,5040,40320};//康托序列
3 inline int cantor(){
4 int ans=0;
5 for(int i=0;i<N;i++)
6 {
7 int cnt=0;
8 for(int k=i+1;k<N;k++)
9 {
10 if(value[k]<value[i])
11 cnt++;
12 }
13 ans+=fac[8-i]*cnt;
14 }
15 return ans;
16 }

反向展开:

View Code
 1 //value数组存放当前排列   
2 const int fac[]={1,1,2,6,24,120,720,5040,40320};//康托序列
3 inline int cantor(Point p){
4 int ans=0;
5 for(int i=0;i<N;i++)
6 {
7 int cnt=0;
8 for(int k=i-1;k>=0;k--)
9 {
10 if(value[k]>value[i])
11 cnt++;
12 }
13 ans+=fac[i]*cnt;
14 }
15 return ans;
16 }

posted on 2011-09-21 14:27  AdaByron  阅读(236)  评论(0编辑  收藏  举报

导航