zoukankan      html  css  js  c++  java
  • 康托展开

    问题1

    给出一个$1 sim n$的全排列$P$, 求它是所有全排列的第几个 (0-based)?

    做法

    从左到右看$P$的每一位, 考虑当前可以确认有多少全排列在$P$之前.
    $*$: 所有第一位是$1 sim P_1 -1$的排列都在$P$之前, 共有 $(P_1-1)(n-1)!$个.
    $P_1, *$: 所有第一位是$P_1$, 第二位小于$P_2$的全排列都在$P$之前, 共有$less_P(2) cdot (n-2)!$个.
    $less_P(k)$: ${P_{k+1}, P_{k+2}, dots, P_{n}}$中小于$P_k$的数的数目.

    $$Rank(P) = sum_{i=1}^{n}less_P(i) cdot (n-i)!$$

    借助这个公式, 可以把一个全排列压缩成一个整数, 范围是$[0, n!-1]$, 这个方法称作康托展开.

    问题2

    给出一个$1 sim n$的全排列$P$的序号$rank(P)=x$, 求出这个全排列. (逆康托展开)

    做法

    从上面的讨论可知, $x$可以看成一个$n$为数, 从左 (高位) 到右 (低位) 每一位的权值分别是$(n-1)!, (n-2)!, dots, 1!, 0!$, 即$x=d_{1}d_{2}...d_{3}d_{n}, d_i = less_P(i) le n-i $.

    类似$k$进制, 我们有
    $$sum_{j=i}^{n}(n-j) cdot (n-j)! < (n-i+1)!$$
    下面证明$sum limits _{i=0}^{n-1} icdot i! < n!$.

    证明: 对$n$用归纳法, $n=1$时显然.
    $sum limits _{i=0}^{n} icdot i! < n! + ncdot n! =(n+1)n! = (n+1)!$

    这样我们就能求出$less_P(1)$到$less_P(n)$, 从而求出$P_1$到$P_n$.

  • 相关阅读:
    初学Listener
    初学filter
    Servlet开发
    伪随机数生成
    枚举类
    LeetCode74——Search a 2D Matrix
    STL——lower_bound()
    LeetCode198——house robber(不懂dp)
    LeetCode171——Excel Sheet Column Number
    参数传递的三种方式
  • 原文地址:https://www.cnblogs.com/Patt/p/6039263.html
Copyright © 2011-2022 走看看