51Nod 3209 康托展开

博客探讨了如何在有重复元素的排列中使用康托展开来确定排列的字典序位置。通过举例和公式解释,说明了计算排列数量及某个特定排列位置的方法,并提供了问题的解决思路和编程技巧。

给出一个排列(可能有重复数字),我们枚举由同样元素组成的所有不同排列,并将这些排列按照字典序从小到大排序,问当前排列排在第几位。

输入格式

第一行输入一个数t,表示测试数据的数量(1≤t≤100000) 之后对于每组数据, 第一行输入一个数n,表示排列中元素个数 (1≤n≤12) 第二行输入n个数ai,表示当前的排列(1≤ai≤12)

输出格式

输出共 t 行,对应排列排序的位置。

输入样例

3
3
1 2 3
3
2 1 2
3
2 1 3

输出样例

1
2
3

数据范围

对于15%的数据,1≤t≤5; 对于55%的数据,1≤t≤2000; 对于100%的数据,1≤t≤100000,1≤n≤12,1≤ai≤12;

在有重复的排列中如何做康托展开呢?约定元素为 a1,a2....ana1,a2....an ,元素出现的次数为 cnt1,cnt2....cntncnt1,cnt2....cntn 。

那么元素的总数量为:

cnt1+cnt2+....cntn=sum∑i=1ncnti=sumcnt1+cnt2+....cntn=sum∑i=1ncnti=sum

首先我们考虑总的排列数量 totaltotal ,根据排列组合公式可知:

total=sum!/cnt1!/cnt2!..../cntn!total=sum!/cnt1!/cnt2!..../cntn!

以 1,1,2,2,2,31,1,2,2,2,3 为例,就是 6!/2!/3!/1!=606!/2!/3!/1!=60 个。

其中以 11 为首的排列 P1P1 ,共有 60/6∗2=2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值