全排列与 康托展开
2017-11-05 15:34
162 查看
对于没有重复元素的全排列来说,存在如下的对应关系
X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!
ai为整数,并且0<=ai<i(1<=i<=n)
这种对应称为康托展开,是一种全排列与整数的双射,n位(0~n-1)全排列后,其康托展开唯一且最大约为n!
可用于压缩状态,可作为Hash函数。
康托展开:
int contor(int num[]){
int k=1;
for(int i=1;i<=n;i++){
int t=0;
for(int j=i+1;j<=n;j++){
if(num[i]>num[j]){
t++;
}
}k+=t*fac[n-i];
}
return k;
}康拓逆展开:
void recontor(int num[],int k){
int t=0;k--;
bool f[12]={0};
for(int i=1;i<=n;i++){
t=k/fac[n-i];
int j;
for( j=1;j<=n;j++){
if(!f[j]){
if(t<=0) break;
t--;
}
}
num[i]=j;
f[j]=1;
k%=fac[n-i];
}
}
X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0!
ai为整数,并且0<=ai<i(1<=i<=n)
这种对应称为康托展开,是一种全排列与整数的双射,n位(0~n-1)全排列后,其康托展开唯一且最大约为n!
可用于压缩状态,可作为Hash函数。
康托展开:
int contor(int num[]){
int k=1;
for(int i=1;i<=n;i++){
int t=0;
for(int j=i+1;j<=n;j++){
if(num[i]>num[j]){
t++;
}
}k+=t*fac[n-i];
}
return k;
}康拓逆展开:
void recontor(int num[],int k){
int t=0;k--;
bool f[12]={0};
for(int i=1;i<=n;i++){
t=k/fac[n-i];
int j;
for( j=1;j<=n;j++){
if(!f[j]){
if(t<=0) break;
t--;
}
}
num[i]=j;
f[j]=1;
k%=fac[n-i];
}
}
相关文章推荐
- UVA 11525 Permutation-不重复全排列的第n项-(康托展开)
- 求排列中第k大的数--逆康托展开
- 康托展开 全排列
- 康托展开和康托逆展开解决第K个排列问题
- 51nod:第K个幸运排列(数位dp & 逆康托展开)
- 求某个数是排列中的第几个--康托展开
- 关于全排列问题的总结(康托展开)
- 【数学】康托和逆康托展开(全排列顺序问题)
- 康托展开(求该排列是第几大的) 模板
- noip2004 火星人 (按照康托展开,从一个排列生成下一个排列)
- 全排列方法二(康托展开)
- 康托展开:对全排列的HASH和还原,判断搜索中的某个排列是否出现过
- 康托展开(方便排列计数)
- 蓝桥 排列序数(康托展开)
- 全排列计算(康托展开)
- 排列序列 (康托展开)
- 2017蓝桥杯官方模拟题 排列序数(康托展开)
- 康托展开(用于全排列与整数的转换)
- 蓝桥模拟题 排列序数(康托展开)
- 全排列散列 - (康托展开 和 逆康托展开)