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

    原理:

    举个例子来说明康拓展开的应用:

    已知1,2,3,4,5五个数的全排列,给出一个排列34152,问该排列在全排列中是第几个。而康托展开的值就是这个排名。

    • 首位是3,比它小而且没有出现过的数有1,2两个,所以为          2 * 4!;
    • 第二位是4,比它小而且没有出现过的数有1,2两个,所以值为  2 * 3!;
    • 第三位是1,没有比它小而且没有出现过的数,所以值为            0 * 2!;
    • 第四位是5,比它小而且没有出现过的数有2一个,所以值为     1  * 1 !;
    • 第五位是2,没有比它小而且没有出现过的数,所以值为            0  *  0!;

    最终相加的结果是61,所以34152在全排列中是第61个。

    实现的代码为:

     1 int FAC[20];   // 阶乘
     2 int cantor(int *a, int n)
     3 {
     4     FAC[1] = 1;
     5     for(int i = 1; i <= 20; i++)//求阶乘
     6         FAC[i] = FAC[i-1] * i;
     7     int x = 0;
     8     for (int i = 0; i < n; ++i) {
     9         int smaller = 0;  // 在当前位之后小于其的个数,这里很神奇,
    10         for (int j = i + 1; j < n; ++j) {//最终的结果就是小于该数却没有出现过的数的个数
    11             if (a[j] < a[i])
    12                 smaller++;
    13         }
    14         x += FAC[n - i - 1] * smaller; // 康托展开累加
    15     }
    16     return x;  // 康托展开值
    17 }
    18 /*这里在求小于该数却没有出现过的数的时候,如果n很大就会有超时的危险,可以用线段树来实现*/

     1 int FAC[20];   // 阶乘
     2 int vis[maxn];
     3 int cantor(int *a, int n)
     4 {
     5     FAC[1] = 1;
     6     for(int i = 1; i <= 20; i++)//求阶乘
     7         FAC[i] = FAC[i-1] * i;
     8     int x = 0;
     9     for (int i = 0; i < n; ++i) {
    10         int smaller = 0; 
    11         vis[a[i]] = 1;
    12         for (int j = 0; j < i; ++j) {
    13             if (!vis[j] && a[j] < a[i])
    14                 smaller++;
    15         }
    16         x += FAC[n - i - 1] * smaller; // 康托展开累加
    17     }
    18     return x;  // 康托展开值
    19 }
    20 /*从前边开始的统计如上*/
  • 相关阅读:
    安装wampserver2时出现的问题
    微信相关信息
    YII CDbCriteria总结
    discuz@功能的代码
    音乐搜索并生成播放功能
    php生成json和js解析json
    Discuz!提取文章标签
    ⑦ vue项目结构study
    ⑤ elementui 使用字符填充table空白表格项
    ④ keep-alive缓存组件,操作之后需要重新获取数据--activated
  • 原文地址:https://www.cnblogs.com/sykline/p/9737831.html
Copyright © 2011-2022 走看看