poj 1286 Necklace of Beads & poj 2409 Let it Bead(初涉polya定理)
Posted yfceshi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj 1286 Necklace of Beads & poj 2409 Let it Bead(初涉polya定理)相关的知识,希望对你有一定的参考价值。
http://poj.org/problem?id=1286
题意:有红、绿、蓝三种颜色的n个珠子。要把它们构成一个项链,问有多少种不同的方法。旋转和翻转后同样的属于同一种方法。
polya计数。
搜了一篇论文Pólya原理及其应用看了看polya究竟是什么东东。它主要计算所有互异的组合的个数。对置换群还是似懂略懂。用polya定理解决这个问题的关键是找出置换群的个数及哪些置换群,每种置换的循环节数。像这样的不同颜色的珠子构成项链的问题能够把N个珠子看成正N边形。
Polya定理:(1)设G是p个对象的一个置换群。用k种颜色给这p个对象,若一种染色方案在群G的作用下变为还有一种方案,则这两个方案当作是同一种方案,这种不同染色方案数为:。
(2) 对于N个珠子的项链,共同拥有n种旋转置换和n种翻转置换。
对于旋转置换:每种置换的循环节数c(fi) = gcd(n,i)。(i为一次转过多少个珠子)
对于翻转置换:假设n为奇数。共同拥有n种翻转置换。每种置换的循环节数c(f) = n/2 + 1;
假设n为偶数,c(f) = n/2的置换有n/2个; c(f) = n/2 + 1的置换有n/2个。
直接带入公式就KO了。
poj 1286
#include <stdio.h> #include <iostream> #include <algorithm> #include <set> #include <map> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #define LL long long #define _LL __int64 #define eps 1e-8 using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 10; int n; _LL ans; int gcd(int a, int b) { if(b == 0) return a; return gcd(b,a%b); } int main() { while(~scanf("%d",&n)) { if(n == -1) break; if(n == 0) //不考虑n=0的情况,会导致RE { printf("0\\n"); continue; } ans = 0; // n 种旋转置换 for(int i = 1; i <= n; i++) ans += pow(3.0,gcd(n,i)); //m种翻转置换 if(n & 1) { ans += n * pow(3.0,n/2+1); } else { ans += n/2 * pow(3.0,n/2); ans += n/2 * pow(3.0,n/2+1); } ans = ans/2/n; printf("%I64d\\n",ans); } return 0; }
poj 2409
#include <stdio.h> #include <iostream> #include <algorithm> #include <set> #include <map> #include <vector> #include <math.h> #include <string.h> #include <queue> #include <string> #include <stdlib.h> #define LL long long #define _LL __int64 #define eps 1e-8 using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 10; int c,s; _LL ans; int gcd(int a, int b) { if(b == 0) return a; return gcd(b,a%b); } int main() { while(~scanf("%d %d",&c,&s)) { if(c == 0 && s == 0) break; ans = 0; for(int i = 1; i <= s; i++) ans += pow(c*1.0,gcd(s,i)); if(s & 1) { ans += s * pow(c*1.0,s/2+1); } else { ans += s/2 * pow(c*1.0,s/2); ans += s/2 * pow(c*1.0,s/2+1); } ans = ans/2/s; printf("%I64d\\n",ans); } return 0; }
以上是关于poj 1286 Necklace of Beads & poj 2409 Let it Bead(初涉polya定理)的主要内容,如果未能解决你的问题,请参考以下文章
POJ 1286 Necklace of Beads(项链的珠子)