一些经典的排列问题
组合数学的研究对象中,根据有无顺序,一般分为排列问题和组合问题。排列与组合的根本区别在于前者与元素的顺序有关,后者与元素的顺序无关。
在排列与组合的问题中,经常会出现计数问题,解决计数问题的思路一般有以下三种:
1.只取要的。即把各种符合条件的情形枚举出来,再利用加法原理求和;2.先全部取,再减去不要的。即把所有可能的情形枚举出来,再减去不符合条件的情形;3.先取后排。即先把各步中符合条件的排列或组合计算出来,再根据乘法原理求积 or dp.
排列数的定义:
从n个元素的集合S中,有序地选出r个元素,r ≤ n,叫做S的一个r排列,排列总数记作P(n,r).根据乘法原理,
P(n,r)=n*(n-1)*(n-2)*......*(n-r+1) = n! / (n-r)!特别地P(n,n) = n!
简单排列的分类:
从n个不同元素中可以重复地选取出m个元素的排列,叫做相异元素可重复排列.其排列方案数为n^m种.如果在n个元素中,有n1个元素彼此相同,有n2个元素彼此相同......又有nm个元素彼此相同,并且n1+n2+......+nm=n,则这n个元素的全排列叫做不全相异元素的全排列.想要计算这种情况下的排列数P,那么这种情况下的排列中相同的元素是可以任意交换顺序的,也就是说每一种元素可以交换的顺序数为ni! 所有元素可以交换的顺序数*P就是全排列数,全排列数是不考虑元素的重复而只考虑元素的下标的,所以可以得到公式:
P = n!/(n1!*n2*......*nm!).如果n1+n2+......+nm=r,那么从n个元素中选r个的方案数P=P(n,r)/(n1!*n2!*......*nm!).
例1:将1、2、3、4、5五个数进行排列,要求4一定要排在2的前面。问有多少种排法.
分析:采用解决计数问题的第一个方法.因为1,3,5这3个数不受限制,可以任意排列,所以先对1,3,5做全排列,排列数为3!再来考虑2,4怎么放.先放4,4对应的有4个位置可以放,从前往后每个位置2分别有4,3,2,1个位置可以放,根据乘法原理,方案数为1*4+1*3+1*2+1*1=10.最后的解为3!*10.
例2:有3个相同的黄球、2个相同的蓝球、4个相同的白球排成一排,问有多少种不同的排法?
分析:公式,P = P(10,4) / (2! * 1! * 1!)种.
例3:把两个红球、一个蓝球、一个白球放到10个编号不同的盒子中去,每个盒子最多放1个球,有多少种放法?
分析:每个盒子最多放1个求,盒子是不同的,那么就要取4个盒子来放球,不同盒子放什么球是有区别的,与元素的顺序有关,那么根据不全相异的选排列公式,P=P(10,4)/(2!*1!*1!)种.这种问题既跟盒子的编号有关,也跟球的颜色有关,先取的P(10,4)是取4个盒子根据不同的顺序排列,因为盒子的顺序是变化的,放球的顺序是怎么样的就无所谓了,如果又乘一个P(4,4),那么球和盒子就分别变换顺序,导致重复统计,所以只需一个P(10,4)就好了.最后除以会重复统计的方案数就是答案了.
错位排列:
对于一个排列(a1,a2......an),任意一个位置i上的数不是ai,那么这个排列就是一个错位排列,设Dn表示{1,2,......,n}的错位排列的个数,那么Dn = n! * (1 - 1/1! + 1/2! - 1/3! + 1/4! -...(-1)^n/n!).公式的推导可以采用解决计数问题的第二种方法.全排列的数量为n!设Ai是在{1,2,......,n}的所有排列中第i个位置上的元素恰好是i的左右排列组成的集合,|Ai| = (n-1)!,因为一个元素固定了,剩下的元素就可以随便排列了.那么|Ai ∩ Aj| = (n-2)!若有k个A取交集,集合的大小为(n-k)!.用总的排列数减去不满足要求的排列数,根据容斥原理,先减去有1位满足要求的,再加上有2位满足要求的,再减去有3位满足要求的......根据之前推导出的公式,有1位满足要求的方案数是C(n,1)*(n-1)!,有k位满足要求的方案数是C(n,k)*(n-k)!那么Dn = n! - C(n,1)*(n-1)! + C(n,2)*(n-2)! - C(n,3)*(n-3)! + C(n,4)*(n-4)......变形一下,就能得到一开始的那个公式了.
例4:书架上有6本书,编号分别为1~6,取出来再放回去,要求每本书都不在原来的位置上,有多少种排法?
分析:错位排列问题.如果不知道公式可以先打个表找找规律:f(1) = 0,f(2) = 1,f(3) = 2,f(4) = 9,f(5) = 44,f(6) = 265.可以发现:
f(n) = (n-1) * (f(n-1) + f(n-2))
圆排列:
从n个不同元素中选出r个元素,不分首尾地围成一个圆圈的排列叫做圆排列,其排列方案数为P(n,r)/r,如果r=n,则有n!/n = (n-1)!种.
为什么是这样的呢?考虑r=n的情况.如果是一条链上的排列,那么方案数很显然就是n!,放在环上,环可以从任意一个地方断掉成为一条链,那么第一个数不论放在哪一个位置,都可以从那个位置破环成链,放在链上,第一个数就必须放在首位置上.其余的数可以随意排列,就得到了上面这个公式.
例5:有男女各5人,其中3对是夫妻,沿10个位置的圆桌就座,若每队夫妻都要坐在相邻的位置,问有多少种坐法?
分析:和上面的球装箱差不多.每个人是有差别的,圆桌在位次上也是有差别的.如果把其中的3对夫妻绑在一起变成1个人,那么原来10个位置的圆桌就变成了7个位置,7个位置上的圆排列数是6!,接下来再来考虑每对夫妻的座次情况,每一对夫妻都有两种情况,要么是丈夫在左,要么是妻子在左,3对夫妻就有2^3种情况,总方案数就是6!*2^3.几个东西互相有约束,那么可以先作为一个整体,求出方案数,再在整体中求出方案数,这样就能在没有约束的情况下求方案数.需要注意的是作为整体后,一些相应的条件也要改变,比如这道题中位置数量.
如何生成全排列?
STL中的next_permutation函数就可以很高效地实现.不停地调用next_permutation(a + 1,a + 1 + n)就能生成全排列.