【康托展开】

康托展开:

1.定义:给一个n个不同数字的排列,求所有排列中比该排列要小的个数X

2.式子:$X=a_n*(n-1)!+a_{n-1}*(n-2)!+……+a_1*0!$,其中$a_i$表示第1位到第i-1位上的数字中,比第i位(从右往左数)数字的个数小的数量。

3.例子:如 {1、2、3、4}的一个排列 {2、1、4、3}:

  X=1*3!+0*2!+1*1!+0*1!= 7。

逆康托展开

1.猜想:既然我们可以通过1-n的一个排列S,求出X(S),那么是否给定一个X(S)可以求出S呢?

2.结论:可以。

  对于给定的X(S)我们第一次对(n-1)!取商和余,商即为$a_n$;

  第二次对让第一次的余(n-2)!取商和和余,商即为$a_{n-1}$;

  ……

  求出$a$以后,我们对$a$进行反解,即X(S)

3.例子:X(S)=7

  X=1*3!+0*2!+1*1!+0*0!

  所以$a$={1、0、1、0},那么$s_4=2$,$s_3=1$,$s_2=4$,$s_1=3$。

  反解成功。

原文地址:https://www.cnblogs.com/Troywar/p/8523619.html

时间: 2024-11-09 00:36:34

【康托展开】的相关文章

康托展开和逆康托展开

问题:给定的全排列,计算出它是第几个排列? 对于全排列,不清楚的可以参考全排列 方法:康托展开 对于一个长度为 n 的排列 num[1..n], 其序列号 X 为 X = a[1]*(n-1)! + a[2]*(n-2)! +...+ a[i]*(n-i)! +...+ a[n-1]*1! + a[n]*0! 其中a[i]表示在num[i+1..n]中比num[i]小的数的数量 写做伪代码为: Cantor(num[]) X = 0 For i = 1 .. n tp = 0 For j = i

康托展开

对于n个数的全排列,共有n!中排列方式,如何求某一个序列在整个排列中的次序(从小到大)? 以9的全排列举例:842697513是1-9全排列的第几个?(高中数学排列组合问题,只需要做到不重不漏) 首先看第一位为8,那么第一位为1-7的全排列都比它小,共有7*8!个. 在第一位为8的情况下,其次看第二位为4,那么第二位为1-3的全排列都比它小,共有1*3*7!个. 在第一位为8,第二位为4的情况下,那么第三位为1的全排列都比它小,共有1*1*6!个. 在第一位为8,第二位为4,第三位为2的情况下,

Aizu 0121 Seven Puzzle (康托展开+bfs)

Seven Puzzle Time Limit : 1 sec, Memory Limit : 65536 KB 7パズルは8つの正方形のカードとこれらのカードがぴたりと収まる枠を使って行います.それぞれのカードは互いに区別できるように.0,1,2....7と番号がつけられています.枠には.縦に2個.横に4個のカードを並べることができます. 7パズルを始めるときには.まず枠にすべてのカードを入れます.枠のなかで0のカードだけは.上下左右に隣接するカードと位置を交換することができます.たとえば.枠

HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3

http://acm.hdu.edu.cn/showproblem.php?pid=3567 相比Eight,似乎只是把目标状态由确定的改成不确定的,但是康托展开+曼哈顿为h值的A*和IDA*都不过,而且也不好控制字典序 换个角度想,虽然起始状态有很多,但是到底哪一位是1,哪一位是2不是最重要的,最重要的是和目标状态对应,所以可以把起始状态重新编码为"12345678"这种形式(先不考虑X),然后目标状态也对应过去,当考虑X的时候,我们可以认为起始状态只有9种,分别是'X'在各个位置的

康托展开和逆展开

康托展开: 给定一个排列(由n个数排列而成),我们可以计算出该排列在由n个数组成的所有排列中排名第几(按字典序),这就是康托展开. 比如由4个数1,2,3,4组成排列 那么2413在所有的排列中排第几呢? 首先计算第一位数字比2小的排列有多少种,即 1 * fac[3],怎么得来的呢?首先比2小的数字只有1个,那么第一位数字只有一种选择,剩下的三位数字有fac[3]种选择,所以是1 * fac[3] 现在当第一位固定是2,那么来计算第二位数字比4小的排列有多少种呢?首先比4小的数字有1个,那么第

HDU 1043 Eight(反向BFS+打表+康托展开)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1043 题目大意:传统八数码问题 解题思路:就是从“12345678x”这个终点状态开始反向BFS,将各个状态记录下来,因为数字太大所以用康托展开将数字离散化. 代码: 1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<st

hdu1430魔板(广搜+康托展开+string应用)

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2420    Accepted Submission(s): 511 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜色

hdu 1430 (BFS 康托展开 或 map )

第一眼看到这题就直接BFS爆搜,第一发爆了内存,傻逼了忘标记了,然后就改,咋标记呢. 然后想到用map函数,就8!个不同的排列,换成字符串用map标记.然后又交一发果断超时,伤心,最恨超时,还不如来个wa算了. 然后卡着了,后来上网上搜了,要用康托展开,康托展开是什么鬼?然后学习了一下,就是个映射,感觉和map差不多. http://blog.csdn.net/zhongkeli/article/details/6966805这个学习一下康托展开. 其实本题的关键不是康托展开,而是置换. 以12

HDU1430 BFS + 打表 + 康托展开

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1430 , 一道比较好的题. 这道题要用到很多知识,康托展开.BFS.打表的预处理还要用到一一映射,做完受益匪浅. 其实这道题也可以用双向BFS来写,思路也已经有了,过几天再来写. 本文持续更新. 先说搜索部分: 对于魔板的每一个状态,都可以进行A.B.C三种操作,所以按照图论来讲,就是操作前的状态可以到达操作后的状态,所以就这样转换成了广搜问题. 这里要注意一点,由于题目要求字典序最小的,所以搜索的

康托展开与八数码问题

康托展开的公式是 X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! 其中,ai为当前未出现的元素中是排在第几个(从0开始). 举个例子来说明一下: 例如,有一个数组 s = ["A", "B", "C", "D"],它的一个排列 s1 = ["D", "B", "A", "C"],现在要把