第二节 排列及其逆序数
- 格式:pptx
- 大小:441.37 KB
- 文档页数:10
排列与逆序◼概念◼计算(1) 定义例如⚫排列及其逆序数1, 2, 3, 4可组成24=4!个不同的4阶排列.1, 2, …, n 可组成n !个不同的n 阶排列.由1, 2, ···, n 共n 个数码组成的一个有序数组称为一个n 阶排列.在4 阶排列1234 及1324 中,我们规定各元素之间有一个标准在1324 中,n 个不同的自然数,规定由小到大为1234为自然称为标准排列. 3在2之前,称这两个数字构成一个逆序.(2) 定义次序,标准次序.顺序,()n s t i i i i i 21例如定义 3 2 5 1 4逆序逆序逆序t s i i >,在一个排列中,则称这两个数组成一个逆序.(3) 排列的逆序数若数排列32514中,逆序逆序⚫逆序数为奇数的排列称为奇排列;⚫逆序数为偶数的排列称为偶排列.排列的奇偶性定义排列的逆序数.一个排列中所有逆序的总数称为此计算排列逆序数的方法分别计算出排列中每个元素前面比它大的数码个数之和,即算出排列中每个元素的逆序数,每个元素的逆序数之总和即为所求排列的逆序数.例1解在排列32514中,3排在首位,2的前面比2大的数只有一个3,于是排列32514 的逆序数为13010++++=t .5=5的前面没有比5大的数,1的前面比1大的数有3个,4的前面比4大的数有1个,求排列32514的逆序数.逆序数为0;故逆序数为1;其逆序数为0;故逆序数为3;故逆序数为1;把一个排列中某两个数字位置互换,例如定义我们把对排列所施行的这种变换排列的奇偶性发生了变化.而其余的数字位置保持不变,就构成了一个53412经过1, 5对换得到13452,τ(5341 2)=3+3+1+1=8, 这时有τ(13452)=3. 新的排列.称为排列的一个对换.一次对换改变排列奇偶性.证明1、相邻对换设…k j … (1)对换k , j 后再设…j k … (2)因为2τ⎧=⎨⎩所以,相邻对换结论成立.11τ−,11τ+,k j <当时,k j >当时;定理2、一般情形因为…k i 1i 2… i s j ……i 1i 2…i s k j ……j i 1i 2…i s k …所以,结论成立.s+1次相邻对换…………推论任何一个n阶排列都可以通过对换化成标准排列,并且所作对换的次数的奇偶性与该排列的奇偶性相同.重新考察二阶、三阶行列式每项的符号,可以得到以下规律:当行标取成标准排列,由列标排列的奇偶性决定每项前的正负号.11122122a a a a =111213212223313233a a a a a a a a a =121212()12(1)j j j j j j a a τ−∑123123123()123(1)j j j j j j j j j a a a τ−∑故二阶、三阶行列式也可以这样写:思考题排列n(n-1)⋯321的逆序数是______(1)2n n −。
§ 2 全排列及其逆序数一、全排列个不同元素排成一列。
可将个不同元素按1~ 进行编号,则个不同元素的全排列可看成这个自然数的全排列。
个不同元素的全排列共有种。
逆序的定义:取一个排列为标准排列,其它排列中某两个元素的次序与标准排列中这两个元素的次序相反时,则称这两个元素构成一个逆序。
通常取从小到大的排列为标准排列,即 1~ 的全排列中取123 为标准排列。
二、逆序及逆序数逆序数的定义:一个排列的逆序数的总数称为逆序数。
逆序数为偶数称为偶排列,逆序数为奇数称为奇排列,标准排列规定为偶排列。
逆序数的计算:设为的一个全排列,则其逆序数为其中为排在前,且比大的数的个数。
例:求的逆序数。
解:,逆序数算法在网上看了很多用mergesort求逆序数的代码,发觉很多都不太对,主要是在merge时求本次merge是前后两部分的逆序数过程,其实merge时由于前后两部分都是已经排好序的,假设merge的两个数组分别为a[n1],b[n2],合并时的逆序数就应该=b中所有小于a[1]的个数,小于a[2]的个数,小于a[3]的个数...小于a[n1]的个数之和=a中所有大于b[1]的个数,大于b[2]的个数,大于b[3]的个数...大于b[n2-1]的个数之和。
因此对于此次合并逆序数的个数有两种计算方法,一是以a中元素作为判断来计算,一是以b中元素作为判断来计算。
以a中元素作为为例:计算过程为,每当把a中某一个元素a[i]插入合并后的数组中时,计算b中已经插入合并后的数组中的元素个数ki,把这些所有的ki加起来即为本次合并的逆序数,具体的代码如下其中的iversion为逆序数。
int inversion=0;void merge(int* a,int p,int q,int r){int n1=r-p+1;int n2=q-r;int i,j,k;k=0;int *tmp=new int[n1+n2];for(i=p,j=r+1;i<=r&&j<=q;){if(a[i]<=a[j]){tmp[k]=a[i];inversion+=j-r;i++;k++;}else{tmp[k]=a[j];j++;k++;}}while(i<=r){tmp[k++]=a[i++];inversion+=q-r;}while(j<=q){tmp[k++]=a[j++];}for(i=p;i<=q;i++)a[i]=tmp[i-p];delete [] tmp;}如果所有人是线性排列,那我们的工作就是类似冒泡程序做的工作,,1,2,3,4,5变为5,4,3,2,1 ,耗时n(n-1)/2但是出现了环,也就是说1,2,3,4,5变为3,2,1,5,4也可满足条件我们可以把这个环等分成两个部分,每个部分看成是线性的,再把它们花的时间加起来. 当n是偶数时, 每份人数n/2 ,即(n/2-1)*(n/2)*2当n是偶数时,两份的人数分别是n/2和n-n/2,即(n/2-1)*(n/2)+ ((n-n/2)-1)*(n-n/2)/2*/int main(){int t,n,i,r,s;cin>>t;while(t--){cin>>n;if(n%2==0){r=n/2;s=(n/2-1)*(n/2);}else{r=n/2;n=n-r;s=(r-1)*r/2+(n-1)*n/2;}cout<<s<<endl;}return 0;}若是线形无环,将1-n变为n-1,求逆序数n*(n-1)/2即可(线性代数)但本题由于是环,则在1-n中取一k,将1-n 变为形如k-1,n-(k+1)也可满足条件,比如1,2,3,4,5变为3,2,1,5,4也可满足条件。