51nod_3209 康托展开


没有了解康托展开的可以先去看看:都能看懂的康托展开.
题目对康托展开进行了拓展:有重复数字的康托展开。
参考思路如下:
但是上面说的太过粗略,接下来较为严谨的分析下:

  • 题目中的 t o t a l total total指的是总排列数量: s u m ! sum! sum!是所有元素的排列组合的方式,除以每个元素所占的数量的阶乘,就是去除这个元素的重复所带来的多的排列的方式(高中知识)。
    得出:

total = sum !/ cnt1 ! ·····

  • 首先,要注意的是,一定可以除尽,为什么?从客观的角度想,sum!一定是大于后面的,并且一定含有后面的因子,但是这样想未免太过僵硬,不妨主主观上想,要求的是方案数丫,方案数有不是整数的吗?木有!所以,一定能除尽。

  • Pn = total / sum * cntn,这个公式。可以从多方面思考,total 是总排列数,除以总元素数量,乘以某个元素的个数有什么具体含义呢 ? total / sum 可以看作是任意一个元素在首位置时的排列数,乘以这个的数量,就是这个元素在首位的总排列数。

    但是要注意,total / sum 不一定可以整除。但是 Pn = total * cetn / sum 一定可以整除(这个的答案也是方案数,从主观上看,所得一定是个整数解)。
    所以第二个公式更应该这么写:

Pn = total * cntn / sum

  • 这里,n是在不断缩小的,对应的,total也是不断变化的,cnt也是变化的,所以我们要动态处理,每一次,都要重新求一下对应的值。
  • OK,没看懂也没关系,代码如下
#include<bits/stdc++.h>
#define fi first
#define endl "\n"
#define se second
#define PI acos(-1)
#define int long long
#define inf 0x3f3f3f3f
#define mm(a, b) memset(a, b, sizeof(a))
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define debug freopen("1.in", "r", stdin), freopen("1.out", "w", stdout);
using namespace std;
typedef long long ll;
typedef pair<int , int> PII;
const int P = 1000000007;
const int N = 100010;int a[N];
int ck[N];
bool vis[15];void init()
{ck[0] = 0;ck[1] = 1;for(int i = 2;i <= 12;i ++)ck[i] = ck[i - 1] * i;
}
signed main()
{ios//关流,加快输入速度。init();//预处理所有阶乘。int t;cin >> t;while(t --){int n;cin >> n;int sum = ck[n];//这里的sum 和 上文提到的 total 一样。int cnt[15];//记录每个数字出现的次数。mm(cnt , 0);//初始化次数mm(vis , false);//初始化数字出现状态。for(int i = 0;i < n;i ++)//读入每一个数字,并且记录出现次数。{cin >> a[i];cnt[a[i]]++;}int nn = n;//备份一下n, n表示当前排列的长度,nn表示总共有多少个数int res = 0;//初始化答案。for(int i = 0;i < nn;i ++){mm(vis , false);//计算total,如果一个数已经算过了,就没必要除两次,vis数组用于记录状态。for(int k = i;k < nn;k ++){if(!vis[a[k]]){sum = sum / ck[cnt[a[k]]];vis[a[k]] = true;}}mm(vis , false);//如果后面的数小于当前第一位的数,后面这个数的放在首位的全排列全部都是字典序小于当前排列的答案,每个都要加。for(int j = i + 1;j < nn;j ++){if(a[j] < a[i] && !vis[a[j]]){//满足条件,就计算答案。res = res + sum *cnt[a[j]] / n;vis[a[j]] = true;}    }//去下一个排列前的初始化n --;//排列长度减少1.sum = ck[n];//sum 要重新计算cnt[a[i]] --;//当前这个数已经木得价值,就cnt减去1。}//排序是从0开始,所以答案+1.cout << res + 1 << endl;}   return 0;
}

关于:昨天H - 康托展开题目的探究。相关推荐

  1. hihoCoder 1312:搜索三·启发式搜索(A* + 康托展开)

    题目链接 题意 中文题意 思路 做这题的前置技能学习 康托展开 这个东西我认为就是在排列组合问题上的Hash算法,可以压缩空间. A*搜索. 这里我使用了像k短路一样的做法,从最终状态倒回去预处理一遍 ...

  2. A_Star 康托展开 八数码问题

    A_Star算法是一个主要用bfs实现的寻路算法,当数据量庞大的时候往往有更高的时间效率,可以看成是Dijkstra算法的升级版. "盲目搜索会浪费很多时间和空间, 所以我们在路径搜索时, ...

  3. 历届试题+九宫重排+java_蓝桥杯 历届试题 九宫重排 (bfs+康托展开去重优化)...

    Description 如下面第一个图的九宫格中,放着 1~8 的数字卡片,还有一个格子空着.与空格子相邻的格子中的卡片可以移动到空格中.经过若干次移动,可以形成第二个图所示的局面. 我们把第一个图的 ...

  4. 转换地图 (康托展开+预处理+BFS)

    Problem Description 在小白成功的通过了第一轮面试后,他来到了第二轮面试.面试的题目有点难度了,为了考核你的思维能量,面试官给你一副(2x4)的初态地图,然后在给你一副(2x4)的终 ...

  5. (康托展开解释)+ NYOJ 139 我排第几个

    描述 现在有"abcdefghijkl"12个字符,将其所有的排列中按字典序排列,给出任意一种排列,说出这个排列在所有的排列中是第几小的? 输入 第一行有一个整数n(0<n& ...

  6. 【康拓展开逆康托展开】

    百度百科就够了 自己的体会: 康托展开是基于比他小的前面的个数来进行计算的        另外康托展开也是一个数组到一个数的映射,因此也是可用于hash,用于空间压缩.比如在保存一个序列,我们可能需要 ...

  7. 康托展开式---我排第几+逆康托展开

    之前一直不想看这个康托展开定理因为真的很不理解,但是现在还是勇敢的面对了~  {1,2,3,4,...,n}表示1,2,3,...,n的排列如 {1,2,3} 按从小到大排列一共6个.123 132 ...

  8. HDU 1430 魔板(康托展开+BFS+预处理)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  9. CodeForces - 504B Misha and Permutations Summation(线段树模拟康托展开与逆展开)

    题目链接:点击查看 题目大意:给出两个排列 ppp 和 qqq,现在要求输出 Perm((Ord(p)+Ord(q))modn!)Perm((Ord(p)+Ord(q)) \bmod n!) Perm ...

最新文章

  1. 入门|机器学习中常用的损失函数你知多少?
  2. 预留创建时检查增强点:nbsp;MB_RE…
  3. 路由器和网关的区别?
  4. 前端学习(1433):vue是什么
  5. EditPlus软件自动补全文档htmlbar.acp设置 及 模板文件格式
  6. [转]Messenger:使用消息的跨进程通信
  7. Mob云验证,让身份验证更简单
  8. 中国营养与健康调查(CHNS)2018年最新数据
  9. 如何用vb制作“简单”的表白软件
  10. 人机对话系统的对话管理
  11. HSQLDB:一款基于 Java 的嵌入式关系型数据库
  12. CTO能力知识地图正式发布
  13. java实现发送短信和邮箱
  14. 北京大学计算机科学李丰,北京大学
  15. 第六讲 复数和复指数
  16. 「津津乐道播客」#380 津津有味:厨房重地举目皆是刚需,将就不得
  17. 一次RAC主机资源使用异常导致的节点重启
  18. 元宇宙产业委常务副主任委员甘华鸣:狭义元宇宙9大技术:一种基于狭义元宇宙体系结构的观点
  19. 【Qt】 Fractal Designer 5.0 - Help(中文版)
  20. 无人机指挥系统(Drone Commander)

热门文章

  1. Android获取手机序列号
  2. 【iOS】遍历相册照片
  3. 自动驾驶分级 - 练习测验
  4. WPSOffice双面文档打印边距设置技巧(转)
  5. AI时代,APP运营是否会被淘汰
  6. 【Netty - 解码器】did not read anything but decoded a message 异常
  7. O2O口号容易运营难
  8. 裴礼文数学分析中的典型问题与方法练习 1.1.5 解答貌似有问题.
  9. 河北软件职业技术学院计算机专业在哪个校区,河北软件职业技术学院有几个校区,哪个校区最好及各校区介绍...
  10. 部分选主元matlab,列选主元的高斯消去法-matlab