zoukankan      html  css  js  c++  java
  • 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
    ");
    			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
    ",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
    ",ans);
    	}
    	return 0;
    }
    



  • 相关阅读:
    最大生成树与最小生成树
    有限制的最短路spfa+优先队列
    KM算法(最优匹配)
    网络最大流解方程组
    网络费用流-最小k路径覆盖
    树链剖分-点的分治(点数为k且距离最长的点对)
    树链剖分-点的分治(链的点的个数为k的点对数)
    树链剖分-点的分治(dis[i]+dis[j]==k的点对数量)
    树链剖分-点的分治(dis[i]+dis[j]<=k的点对数量)
    无向图欧拉通路
  • 原文地址:https://www.cnblogs.com/yfceshi/p/6748693.html
Copyright © 2011-2022 走看看