康托展开
2017-07-13 09:45
148 查看
康托展开
对于一个长度为n的排列num[1..n],其序号X为:
比如213:
我们如果将3的全排列从0开始编号,2号对应的正是213。
逆康托展开
根据X的求值公式,可以推断:
也就是说,如果我用X除以(n-1)!,得到商c和余数r。其中c就等于a[1],r则等于后面的部分。
这样依次求解,就可以得到a[]数组了。
比如求解3的全排列中,编号为3的排列:
由于a[i]表示的是num[i+1..n]中比num[i]还小的数字。
那么只需要从num[1]开始,依次从尚未使用的数字中选取第a[i]+1小的数字填入就可以了!
紧接着上面的例子:
231也确实是3的全排列中编号为3的排列。
对于一个长度为n的排列num[1..n],其序号X为:
X = a[1]*(n-1)!+a[2]*(n-2)!+...+a[i]*(n-i)!+...+a[n-1]*1!+a *0! 其中a[i]表示在num[i+1..n]中比num[i]小的数的数量
比如213:
num[] = {2, 1, 3} a[] = {1, 0, 0} X = 1 * 2! + 0 * 1! + 0 * 1! = 2
我们如果将3的全排列从0开始编号,2号对应的正是213。
逆康托展开
根据X的求值公式,可以推断:
a[i]≤n-i, a[i]*(n-i)!≤(n-i)*(n-i)!<(n-i+1)!
也就是说,如果我用X除以(n-1)!,得到商c和余数r。其中c就等于a[1],r则等于后面的部分。
这样依次求解,就可以得到a[]数组了。
比如求解3的全排列中,编号为3的排列:
3 / 2! = 1 ... 1 => a[1] = 1 1 / 1! = 1 ... 0 => a[2] = 1 0 / 0! = 0 ... 0 => a[3] = 0
由于a[i]表示的是num[i+1..n]中比num[i]还小的数字。
那么只需要从num[1]开始,依次从尚未使用的数字中选取第a[i]+1小的数字填入就可以了!
紧接着上面的例子:
a[] = {1, 1, 0} unused = {1, 2, 3}, a[1] = 1, num[1] = 2 unused = {1, 3}, a[2] = 1, num[2] = 3 unused = {1}, a[3] = 0, num[3] = 1 => 2, 3, 1
231也确实是3的全排列中编号为3的排列。
相关文章推荐
- HDU 1043 Eight POJ 1077 Eight (广度搜索,八数码问题,康托展开)
- hdu1043Eight (经典的八数码)(康托展开+BFS)
- 康托展开及其逆运算--我是第几个,第几是谁
- 借助八数码问题,双向广搜,康托展开,逆序数奇偶性
- CF501D Misha and Permutations Summation(康托展开)
- Aizu 0121 Seven Puzzle (康托展开+bfs)
- noip2004 火星人 (按照康托展开,从一个排列生成下一个排列)
- POJ1850 Code(组合+康托展开)
- 八数码(康托展开)
- 康托展开
- UVA11525 Permutation[康托展开 树状数组求第k小值]
- 哈希 — 康托展开
- nyoj 139 我排第几个(康托展开)
- 康托展开&逆康托展开
- 康托展开(有关全排列)
- 全排列与 康托展开
- HDU1043 Eight(八数码:逆向BFS打表+康托展开)题解
- 康托展开
- hdu1043Eight (经典的八数码)(康托展开+BFS)
- 康托展开