【概念】
从 n 个元素的集合 S 中,有序的选出 r 个元素,叫做 S 的一个 r 排列,不同的排列总数记作: 或
如果两个排列所含元素不全相同,或所含元素相同但顺序不同,就会被认为是不同的排列。
【可重排列】
从 n 个不同元素可重复的取出 m 个元素,按照一定顺序排成一列,叫做相异元素可重复排列。
相异元素可重复排列的方案数为:
例如:从1、2、3、4、5 中任取三个出来组成一个三位数,有 P(5,3)=60 种情况,如果每个数字可以重复使用,则有:5^3=125 种情况
【不可重排列】
不可重排列是指在 n 个不同元素中选 r 个元素按照顺序排成一列。
1.选排列
从 n 个不同元素取出 r 个元素,按照一定顺序排成一列,当 r<n 时,叫做从 n 个不同元素取出 r 个不同元素的一种选排列。
使用乘法原理,可以推出选排列 的方案数:
模版:输入两个整数 n、r,输出 A(n,r) 的所有方案
int n,r;
int data[N];
int vis[N];
void Done(int i){
if(i==r){//若相等,说明已经生成一个排列
for(int j=0;j<r-1;j++)//输出排列
printf("%d",data[j]+1);
printf("%d\n",data[r-1]+1);
return;//回溯寻找下一种排列
}
for(int j=0;j<n;j++){
if(!vis[j]){//若没有在该排列前面出现过
vis[j]=true;
data[i]=j;//该位置上就选择j
Done(i+1);
vis[j]=false;
}
}
}
int main(){
memset(vis,false,sizeof(vis));
scanf("%d%d",&n,&r);
Done(0);
return 0;
}
2.全排列
从 n 个不同元素取出 r 个元素,按照一定顺序排成一列,当 r=n 时,叫做 n 个不同元素的全排列。
全排列 的方案数:
C++ 中,头文件<algorithm> 里的 next_permutation() 函数,可产生字典序的全排列。
关于 next_permutation() 函数:点击这里
如下,给出从一组全排列的情况,使用 next_permutation() 函数可以生成下一种的全排列的情况,因此一般先使用 sort() 进行排序,即可生成所有全排列的情况。
int a[N];
int main(){
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
sort(a,a+n);
do{
for(int i=0;i<n;i++)
printf("%d ",a[i]);
printf("\n");
}while(next_permutation(a,a+n));
return 0;
}
【不全相异排列】
1.不全相异元素的选排列
若在 n 个元素中,有 个元素彼此相同,
个元素彼此相同,...,
个元素彼此相同,且
,则这 n 个元素选出 r 个的选排列叫做不全相异元素的选排列。
其排列数计算公式为:
2.不全相异元素的全排列
若在 n 个元素中,有 个元素彼此相同,
个元素彼此相同,...,
个元素彼此相同,且
,则这 n 个元素的全排列叫做不全相异元素的全排列。
其排列数计算公式为:
【错位排列】
设 是
的一个全排列,若对任意的
都有
,则称
是
的错位排列。
用 表示
的错位排列的个数,有:
例题:书架上有 6 本书,编号为 1-6 ,取出来再放回去,要求每本书都不在原来的位置上,有多少种放法?
分析:本题是要求 1-6 的错位排列,使用容斥原理有:
【圆排列】
从 n 个不同元素中选取 r 个元素,不分首尾地围成一个圆圈的排列叫做圆排列,其排列方案数为:
当 r=n 时,则为圆排列的全排列,其排列方案数为:
例题:有男女各 5 人,其中有 3 对夫妇,沿 10 个位置的圆桌就座,若每对夫妇都要坐在相邻的位置上,有多少种坐法?
分析:先让 3 对夫妇中的妻子和其他 4 人就坐,根据圆排列公式,共有 7!/7=6!种坐法,然后每位丈夫都可以做到自己的妻子左右两边,因此共有 6!*2*2*2=5760 种坐法。