组合数学 —— 排列数

【概念】

从 n 个元素的集合 S 中,有序的选出 r 个元素,叫做 S 的一个 r 排列,不同的排列总数记作:A_n^r 或 A(n,r)

如果两个排列所含元素不全相同,或所含元素相同但顺序不同,就会被认为是不同的排列。

【可重排列】

n 个不同元素可重复的取出 m 个元素,按照一定顺序排成一列,叫做相异元素可重复排列。

相异元素可重复排列的方案数为:n^m 

例如:从1、2、3、4、5 中任取三个出来组成一个三位数,有 P(5,3)=60 种情况,如果每个数字可以重复使用,则有:5^3=125 种情况

【不可重排列】

不可重排列是指在 n 个不同元素中选 r 个元素按照顺序排成一列。

1.选排列

从 n 个不同元素取出 r 个元素,按照一定顺序排成一列,当 r<n 时,叫做从 n 个不同元素取出 r 个不同元素的一种选排列。

使用乘法原理,可以推出选排列 A_n^r 的方案数:A_n^r=n*(n-1)*(n-2)*...*(n-r+1)=\frac{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 个不同元素的全排列。

全排列 A_n^r 的方案数:A_n^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_1 个元素彼此相同,n_2 个元素彼此相同,...,n_m 个元素彼此相同,且 n_1+n_2+...+n_m=r,则这 n 个元素选出 r 个的选排列叫做不全相异元素的选排列。

其排列数计算公式为:\frac{A(n,r)}{(n_1!*n_2!*...*n_m!)}

2.不全相异元素的全排列

若在 n 个元素中,有 n_1 个元素彼此相同,n_2 个元素彼此相同,...,n_m 个元素彼此相同,且 n_1+n_2+...+n_m=n,则这 n 个元素的全排列叫做不全相异元素的全排列。

其排列数计算公式为:\frac{n!}{(n_1!*n_2!*...*n_m!)}

【错位排列】

设 (a_1,a_2,...,a_n)是 \{1,2,...,n\} 的一个全排列,若对任意的 i \in \{1,2,...,n\} 都有 a_i\neq i ,则称 (a_1,a_2,...,a_n) 是 \{1,2,...,n\} 的错位排列。

用 D_n 表示 \{1,2,...,n\} 的错位排列的个数,有:D_n=n!*(1-\frac{1}{1}!+\frac{1}{2}!-\frac{1}{3}!+...+\frac{(-1)^n}{n}!)

例题:书架上有 6 本书,编号为 1-6 ,取出来再放回去,要求每本书都不在原来的位置上,有多少种放法?

分析:本题是要求 1-6 的错位排列,使用容斥原理有:

D_6=6!*(1-\frac{1}{1}!+\frac{1}{2}!-\frac{1}{3}!+\frac{1}{4}!-\frac{1}{5}!+\frac{1}{6}!)=265

【圆排列】

从 n  个不同元素中选取 r 个元素,不分首尾地围成一个圆圈的排列叫做圆排列,其排列方案数为:\frac{A(n,r)}{r}

当 r=n 时,则为圆排列的全排列,其排列方案数为:\frac{n!}{n}=(n-1)!

例题:有男女各 5 人,其中有 3 对夫妇,沿 10 个位置的圆桌就座,若每对夫妇都要坐在相邻的位置上,有多少种坐法?

分析:先让 3 对夫妇中的妻子和其他 4 人就坐,根据圆排列公式,共有 7!/7=6!种坐法,然后每位丈夫都可以做到自己的妻子左右两边,因此共有 6!*2*2*2=5760 种坐法。

【例题】

  • 排列2(HDU-1716)(全排列)点击这里
  • Reconciled?(AtCoder-2642)(全排列)点击这里
  • 火星人(洛谷-P1088)(next_permutation() 函数)点击这里
  • 重排列得到2的幂(51Nod-2515)(next_permutation() 函数+打表)点击这里
  • Hard to prepare(2018 ACM-ICPC 徐州赛区网络赛 A)(环形排列+递推)点击这里
  • permutation 1(HDU-6628)(全排列+思维)点击这里
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值