组合数学

来源:互联网 发布:数据挖掘是爬虫吗 编辑:程序博客网 时间:2024/04/29 02:56

组合数学——polya定理及其应用

polya定理 置换群 

    Polya定理

    设有n个对象,G是这n个对象上的置换群,用m种颜色涂染这n个对象,每个对象涂染一种颜色,问有多少种染色方案?一种染色方案在群G的作用下变为另一种方案,则这两种方案当作是一种方案。

    方案数为



 

POJ2409

   题意:一家项链公司生产手镯。n颗珠子形成一个环,用m种颜色给n颗珠子染色,就得到了各种各样的手镯。但是,经过旋转和翻转使之吻合的算同一种方案。

例如,当用2种颜色对5颗珠子进行染色的方案数为8,如下图所示。



 

解:显然,对于这n个对象,有n种旋转和n种翻转。

1. 对于旋转,有c(gi) = gcd(n,i),i为转动几颗珠子。

2. 对于翻转,当n为奇数时,c(gi) = n/2+1;

                   当n为偶数时,有n/2个的循环节数为n/2+1,有n/2个的循环节数为n/2。

Cpp代码  收藏代码
  1. #include <iostream>  
  2. #include <cstdio>  
  3. #include <cstring>  
  4. #include <cmath>  
  5. using namespace std;  
  6.   
  7. typedef __int64 int64;  
  8.   
  9. int gcd(int a, int b)  
  10. {  
  11.     return b==0?a:gcd(b,a%b);  
  12. }  
  13.   
  14. //用m种颜色涂均匀分布在圆环上的n颗珠子的方案数  
  15. int64 polya_circle(double m, int n)  
  16. {  
  17.     int64 result = 0;  
  18.     //旋转  
  19.     for(int i = 1; i <= n; i++)  
  20.         result += pow(m,gcd(n,i));  
  21.     //翻转  
  22.     if(n%2)  
  23.         result += n*pow(m,n/2+1);  
  24.     else  
  25.         result += (pow(m,n/2)+pow(m,n/2+1))*n/2;  
  26.     return result/n/2;  
  27. }  
  28.   
  29.   
  30. int main()  
  31. {  
  32.     int c,s;  
  33.     while(true)  
  34.     {  
  35.         scanf("%d %d",&c,&s);  
  36.         if(c==0&&s==0)  
  37.             break;  
  38.         printf("%I64d\n",polya_circle(c,s));  
  39.     }  
  40.     return 0;  
  41. }  
0 0
原创粉丝点击