这几天看了排列组合的相关知识,有些知识在中学时接触过,这次又学了很多新的知识。
1. 圆周排列:从n个不同的数中不重复的取出取出r个沿一圆周排列,称为一个圆周排列,所有的r-圆周排列数记为 Q(n,r)。
但是圆周排列与排列的不同之处在于圆周排列首尾相邻,如a、b、c、d的4种不同排列abcd, dabc, cdab, bcda,在圆周排列中都是一个排列。
2. 多重集:多重集—元素可以多次出现的集合,即元素可以重复。我们把某个元素ai出现的次数ni(ni=0,1,2,…)叫做该元素的重复数,通常把含有k种不同元素的多重集S记作
3. 容斥原理:如果被计数的事物有A、B、C三类,那么,A类和B类和C类元素个数总和= A类元素个数+ B类元素个数+C类元素个数—既是A类又是B类的元素个数—既是A类又是C类的元素个数—既是B类又是C类的元素个数+既是A类又是B类而且是C类的元素个数。(A∪B∪C = A+B+C - A∩B - B∩C - C∩A + A∩B∩C)
4.Polya定理:设G={π1,π2,π3........πn}是X={a1,a2,a3.......an}上一个置换群,用m中颜色对X中的元素进行涂色,那么不同的涂色方案数为:1/|G|*(mC(π1)+mC(π2)+mC(π3)+...+mC(πk)). 其中C(πk)为置换πk的循环节的个数。
polya定理求循环节个数代码模板:
1. const int MAX=1001;
2. #define CLR(arr,val) memset(arr,val,sizeof(arr))
3. int n,perm[MAX],visit[MAX];//sum求循环节个数,Perm用来存储置换,即一个排列
4. int gcd(int n,int m)
5. { return m==0?n:gcd(m,n%m);
6. }
7. void Polya()
8. { int pos,sum=0;
9. CLR(visit,0);
10. for(int i=0;i<n;i++)
11. if(!visit[i])
12. { sum++;
13. pos=i;
14. for(int j=0;!visit[perm[pos]];j++)
15. { pos=perm[pos];
16. visit[pos]=1;
17. }
18. }
19. return sum;
20.}
这几天还是要抓紧做题,还有及时总结。