polya定理

这是组合数学中著名的定理。用于解决“本质不同的染色方案”计数问题。

问题

现在需要给2×2的棋盘黑白染色。求本质不同的染色方案数。
如果某染色方案经过顺时针旋转后与别的染色方案相同,则称它们本质相同。

暴力

我们先暴力列出每种染色方案: 
59eb6654682d2.png (230×230)
发现本质不同的染色方案数有6种:C1,C2,C6,C10,C12,C16。

burnside引理

burnside引理是polya定理的基础。
为了讨论方便,先给格子编号。
59eb6654682d2.png (230×230)
首先考虑“旋转”的本质——置换。旋转给出了一些置换方式,例如顺时针旋转90∘,用置换的语言说就是“原来的位置是1的现在摆在2,原来位置是2的现在摆在3……”,表示为{2,3,4,1}。类似地,我们搞出所有的置换:
f0∘={1,2,3,4}
f90∘={2,3,4,1}
f180∘={3,4,1,2}
f270∘={4,1,2,3}
接下来就是burnside引理了:
对于每个置换f,我们定义C(f)为在置换 f 下保持不变的方案数。
则有: 本质不同的方案数为C(f)的平均数。
即:ans=1|G|∑f∈GC(f)
用上面的例子来验证一下:
置换f保持不变的方案C(f)
0∘1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1616
90∘1,162
180∘1,10,11,164
270∘1,162
则C(f)的平均数为:16+2+4+24=6,发现确实是答案。

polya定理

上面的burnside引理很好用,然而它需要枚举每个方案,复杂度十分不好。
所以polya定理出来拯救世界了。它提供了一种快速计算C(f)的方法:
考虑置换f,我们一定能把它表示成循环的形式。例如上面的转180∘可以表示为:{3,4,1,2}=(1,3)(2,4)。
令m(f)表示置换f的循环节个数,k表示有多少种颜色。则有:
C(f)=km(f)
我们还是使用之前的例子来验证。
|角度|置换|m(f)|km(f)| |--|--|--| |0∘| {1,2,3,4}=(1)(2)(3)(4)|4|16| |90∘| {2,3,4,1}=(1,2,3,4)|1|2| |180∘| {3,4,1,2}=(1,3)(2,4)|2|4| |270∘| {4,1,2,3}=(1,2,3,4)|1|2|
从上面的例子中我们发现,km(f)确实等于C(f)。现在我们的任务只是求出m(f)了。它显然可以O(n)求出:
int flag[10]={0},i,j,m=0;

for(i=1;i<=4;i++)
    if(flag[i]==0) 
    {
        j=i;
        while(flag[j]==0)
            flag[j]=1,j=f[j];
        m++;
    }
所以现在我们可以以O(np)的时间复杂度来求出整个问题的解。其中p表示置换数量。
是不是很简单?

评论

此博客中的热门博文

Specifying Systems 第五章笔记

氢氧化铁