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

    1. 康托展开

    X = A[0] * (n-1)! + A[1] * (n-2)! + … + A[n-1] * 0! 

    A[i] 指的是位于位置i后面的数小于A[i]值的个数,后面乘的就是后面还有多少个数的阶乘

    tips:这个算出来的数康拖展开值,是在所有排列次序 - 1的值,因此X+1即为在全排列中的次序,康托展开可逆(自然数 -> 序列)。

    ▲:康托展开的实质是计算当前排列在所有由小到大全排列中的名次。

    ▲:康托展开的原理就是从某个排序组合的首位开始,找出比当前这位数的个数,且之前没有出现过的数的个数乘以对应的阶乘,结果累加就是我们要求的值。//阶乘就理解为以前学过的排列组合,而不同数的阶乘也对数的次序进行了划分,如n=5时,1开头的数,就分布在1到4!。2开头的数,就分布在4!+1到2*4!

     1 int cantor(int *a,int n)
     2 {
     3     int ans=0;
     4     for(int i=0;i<n;i++)
     5     {
     6         int x=0,c=1,m=1;
     7         for(int j=i+1;j<n;j++)
     8         {
     9             if(a[j]<a[i]) x++;
    10             m*=c++;
    11         }
    12         ans+=m*x;
    13     }
    14     return ans;
    15 }

    2. 逆康托展开

    对数X逐个mod(n-i)!,商为几,则表示在第i位(i从第一位开始)后有几个数,然后用余数继续除阶乘求余。

    ▲:原理结合上面,可知在求余数的过程中,其实就是在给这些数定位

     1 void obcantor(int x,int n) //O(n^2)
     2 {
     3     vector<int>v; //存放当前可选数
     4     vector<int>a; //所求序列
     5     int ft[10],id=1;
     6     ft[0]=1;
     7     for(int i=1;i<=n;i++)
     8     {
     9         v.push_back(i);
    10         id*=i;
    11         ft[i]=id;
    12     }
    13     for(int i=n-1;i>=0;i--)
    14     {
    15         int s=x/ft[i];
    16         int t=x%ft[i];
    17         x=t;
    18         sort(v.begin(),v.end());
    19         a.push_back(v[s]); //剩余数里第t+1个
    20         v.erase(v.begin()+s);
    21     }
    22     //for(int i=0;i<n;i++)
    23     //    cout<<a[i]<<" ";
    24 }
  • 相关阅读:
    haproxy 2.5 发布
    cube.js sql 支持简单说明
    基于graalvm 开发一个cube.js jdbc driver 的思路
    apache kyuubi Frontend 支持mysql 协议
    oceanbase 资源池删除说明
    基于obd 的oceanbase 扩容说明
    jfilter一个方便的spring rest 响应过滤扩展
    cube.js schema 定义多datasource 说明
    typescript 编写自定义定义文件
    meow 辅助开发cli 应用的工具
  • 原文地址:https://www.cnblogs.com/XXrll/p/11256393.html
Copyright © 2011-2022 走看看