組合數學的研究對象中,根據有無順序,一般分為排列問題和組合問題。排列與組合的根本區別在於前者與元素的順序有關,后者與元素的順序無關。
在排列與組合的問題中,經常會出現計數問題,解決計數問題的思路一般有以下三種:
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)就能生成全排列.