康托展开

康托展开是全排列到自然数的双射。

x=a[ n ]*( n-1 )!+a[ n-1 ]*( n-2 )!+...+a[ 1 ]*0;

a[ i ]:代表着原数列中存在多少个比 第 n-i 个数小的数;

例如:3 5 7 4 1 2 9 6 8

现在要设置到自然数的双射:

对于 3: 存在 1 2比他小,且1 2 没出现过

所以 x1 = 2*8!(8是表示除第一位填了1 或2 之后还剩余的空位置)

对于 5:存在 1 2 3 4 但是 3 出现过了,所以只有1 2 4

所以 x2 = 3*7!(第一位为3,第二位为 1 2 4 中的一个,还剩于7个位置没填数 )

对于 7 :存在 1 2 3 4 5 6 但是3 5 出现了,所以只有 1 2 4 6

所以 x3 =  4*6!(同上)

sigma(x)=2*8!+3*7!+4*6!+2*5!+0*4!+0*3!+2*2!+0*1!+0*0!;

所以sigma(x)即为总的状态数。

 

View Code
 1 int  fac[] = {1,1,2,6,24,120,720,5040,40320}; //i的阶乘为fac[i]
 2 /*  康托展开.
 3     {1...n}的全排列由小到大有序,s[]为第几个数  */
 4 int KT(int n, int s[])
 5 {
 6     int i, j, t, sum;
 7     sum = 0;
 8     for (i=0; i<n; i++)
 9     {
10         t = 0;
11         for (j=i+1; j<n; j++)
12             if (s[j] < s[i])
13                 t++;
14         sum += t*fac[n-i-1];
15     }
16     return sum+1;
17 }

 

 

posted @ 2013-03-08 16:36  xxx0624  阅读(214)  评论(0编辑  收藏  举报