集合的排列与组合

来源:互联网 发布:js eval 替代 编辑:程序博客网 时间:2024/04/29 11:53

《Introductory Combinatorics Fifth Edition》学习笔记:

排列和组合的区别在于放置和选择是否和顺序有关。

集合的排列:n元素集合的r排列A(n,r)=n*(n-1)*(n-2)……(n-r+1)=n!/(n-r)!

集合的组合:n元素集合的r组合C(n,r)=n!/(n-r)!/r! [组合不考虑顺序]

问题:将26个英文字母排序,要求a,e,i,o,u任意两个不能连续出现,这样的排序有多少个?

分析:26个英文字母的总排序数是A(26,26)=26!,5个元音字母至少两个连续出现的情况有C(5,2)*A(2,2)*25*A(24,24)=20*2*25!=40*25!,result=(26-40)*25!这显然不对。看来不适宜用减法原理(这样处理,集合2并不是所求集合的“补”,第二集合多计算了)。换一种思路:先把辅音字母排列好,A(21,21).接着用隔板法的思想,在22个空选出5个空再排列,于是得到,C(22,5)*A(5,5).result=21!*5!*22!/[(22-5)!*5!]=21!*22!/17!

循环排列:n个元素的排列不是线性的,而是呈现一个圆状,这样一个固定元素顺序的环在圆上只有一种结果(因为可以旋转,形状不变。可以理解为先固定一个起点元素,再对其他元素排列)。这样算来,3个元素的循环排列是A(3,3)/3=2,n元素的循环排列结果是A(n,n)/n=(n-1)!

n元素集合的循环r排列的数目是s=n!/(n-r)!/r。这是建立在每一部分都含有相同数目的r排列之上的。

问题:有n(3<=n<=20)个人围坐一个圆桌,其中有两人不愿意彼此挨着坐,共有多少圆桌位置设置方法?

分析:彼此挨着坐的人数是2所以这里可以用减法原理的思路来计算,s2=A(2,2)*(n-1-1)*(n-3)!.s1=(n-1)! 所以s=s1-s2=(n-1-2)*(n-2)!=(n-3)*(n-2)! 另外通过改变分析次序来足以安排座位也是可以的,先选一个起点元素,这个起点元素就设为那特殊的两个人之一,然后在他的右边和左边都安排其他非特殊的人,(n-2)*(n-3)*A(n-3,n-3)=(n-3)*(n-2)! [这里不用乘以C(2,1),因为设置起点元素是人为的]

编码:

#include <iostream>#include<cstdio>using namespace std;typedef unsigned long long ull; //ull最多正常表示到22!ull f[23];  void getf(){    f[0]=1;    for(int i=1;i<=65;i++)f[i]=f[i-1]*i;}int main(){    getf();    ull n;    while(cin>>n){        printf("%llu\n",(n-3)*f[n-2]);    }    return 0;}

问题:用20个不同颜色的念珠做成项链,有多少种不同的项链成果?
分析:圆桌解题思路,19!,但是特殊的是项链还可以对称翻转所以s=19!/2.

n元素集合的子集数量:C(n,0)+C(n,1)+C(n,2)+……+C(n,n)=2^n。(因为C(n,t)就是(x+y)^n的项的系数,特别地,当x=1,y=1时(x+y)^n的结果也就等于C(n,0)+C(n,1)+C(n,2)+……+C(n,n)的和,即2^n )


0 0
原创粉丝点击