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|fGC(f)
用上面的例子来验证一下:
置换f保持不变的方案C(f)
01,2,3,4,5,6,7,8,9,10,11,12,13,14,15,1616
901,162
1801,10,11,164
2701,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表示置换数量。
是不是很简单?

评论

此博客中的热门博文

将博客部署到星际文件系统(IPFS)

高中地理必修一知识点总结

一场CF的台前幕后(下)