比如现在给你一N长度的字典序列 让它完全排布开来 如
{ (123) , ( 132) , ( 213 ) , (231) , ( 312 ) , (321) }
当我给你231这一子列的时候 如何确定它在上述集合中的位置呢??
也就是如何知道231在上述集合中是排在第4的位置上的
假设有N位字典序列,第i位的数字记为num[i];
那么这个num[i]在num[i]到num[N]中由小到大排列后的序列号
记为rank[i]
例如 一串数字 53214 中
rank[1]=5 因为53214排序后为12345
rank[2]=3 因为3214排序后为1234
rank[3]=2 因为214排序后为124
rank[4]=1 因为14排序后为14
rank[5]=1 因为4排序后为4
那么 当给你一串长度为N的字典排列的时候,如何求出它在这个排列表里的排名呢?经过总结后得出以下的计算公式
自行取例进行验证
对于通过程序求出字典子列的序列号,具体的算法过程描述如下
给定你一串长度为N的字典子列,P1 P2 P3 P4...........PN;
1.构造一个长度也为N的一维数组num[N+1]并将上述字典子列存贮在这个二维数组中
如num[1]=P1,num[2]=P2,num[3]=P3........num[N]=PN,
2.逐个逐个求出rank[i],即求出P1在P1到PN的位置,P2在P2到PN的位置。。。。。。。。。
3.在进行逐个逐个求和;
具体代码的实现如下,
#include<iostream>
using namespace std;
const int MAX=10;
int a[MAX+1];
int b[MAX+1];
int RANK[MAX+1];
int factorial(int n);
int main( )
{
int n,m,i,j;
while(cin>>n)
{
long long sum=1;
m=n;
for( i=1;i<=n;i++)
cin>>a[i];
for( i=1;i<=n;i++)
b[i]=i;
for( i=1;i<=n;i++)
for( j= 1;j<=m;j++)
if(a[i]==b[j])
{
RANK[i]=j;
if(j != m)
while( j != m ) {a[i]=a[i+1];i++;}
--m;
break;
}
for( i=1;i<=n-1;i++)
sum+=(RANK[i]-1)*factorial(n-i);
cout<<sum<<endl;
}
return 0;
}
int factorial(int n)
{
return n==0?1:factorial(n-1)*n;
}