【Polya计数+背包】HDU6360 Kaleidoscope

版权声明:这是蒟蒻的BLOG,神犇转载也要吱一声哦~ https://blog.csdn.net/Dream_Lolita/article/details/82946121

【题目】
原题地址
一个正十二面体,用 n n 种颜色涂色,第 i i 种颜色至少要用 c i c_i 次,求方案数。

【解题思路】
polya好题。

首先写出所有置换。

不动: 1 1
对棱中点连线旋转: 30 1 2 = 15 \frac {30*1} 2 =15
对顶点连线旋转: 20 2 2 = 20 \frac {20*2} 2=20
对面中点连线旋转: 12 4 2 = 24 \frac {12*4} 2 = 24

接下来我们需要证明这是一个置换群。
然而这个东西实在是太难搞了,我们只能YY一下,它就是一个群。

那么现在四个置换群循环节长度分别为 1 , 2 , 3 , 5 1,2,3,5 ,对应循环节个数 60 , 30 , 20 , 12 60,30,20,12
也就是说现在我们要计算的就是染完每种循环的方案数,这个用一个背包就可以解决。
f [ i ] [ j ] f[i][j] 表示前 i i 种颜色,染了 j j 个循环节的方案数,那么我们有:
f [ i ] [ j ] = k = c i j f [ i 1 ] [ j k ] × ( j k ) f[i][j]=\sum_{k=c_i}^j f[i-1][j-k]\times {j \choose k}

一个问题是模数不一定是素数,那最后除法除不尽。
我们可以将模数先乘以 60 60 ,这样计算除的结果一定是整除 60 60 的,最后再将答案除以 60 60 即可,需要使用快速乘。

【参考代码】

#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef long double ldb;
const int N=65;
const ldb eps=1e-8;
int T,n,m;
int sum[5],c[N],d[]={1,2,3,5},num[]={1,15,20,24};
LL mod,ans,C[N][N],f[N];

void up(LL &x,LL y) {x+=y;if(x>=mod)x-=mod;}
LL upm(LL x) {return x>=mod?x-mod:x;}
LL mul(LL x,LL y) {return (x*y-(LL)(x/(ldb)mod*y+eps)*mod+mod)%mod;}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("HDU6360.in","r",stdin);
	freopen("HDU6360.out","w",stdout);
#endif
	scanf("%d",&T);
	while(T--)
	{
		memset(sum,0,sizeof(sum));ans=0;
		scanf("%d%d",&n,&m);mod=(LL)m*60;
		for(int i=0;i<=60;++i)
		{
			C[i][0]=C[i][i]=1;
			for(int j=1;j<i;++j) C[i][j]=upm(C[i-1][j-1]+C[i-1][j]);
		}
		for(int i=0;i<n;++i)
		{
			scanf("%d",&c[i]);
			for(int j=0;j<4;++j) sum[j]+=(c[i]+d[j]-1)/d[j];
		}
		for(int i=0;i<4;++i)
		{
			int tn=60/d[i];
			if(sum[i]>tn) continue;
			memset(f,0,sizeof(f));f[0]=1;
			for(int j=0;j<n;++j)
			{
				int cnt=(c[j]+d[i]-1)/d[i];
				for(int k=tn;~k;--k)
				{
					LL res=0;
					for(int l=cnt;l<=k;++l) up(res,mul(C[k][l],f[k-l]));
					f[k]=res;
				}
			}
			up(ans,mul(f[tn],num[i]));
		}
		ans/=60;printf("%lld\n",ans%mod);
	}

	return 0;
}

【总结】
我说它是一个群,它就是一个群。

猜你喜欢

转载自blog.csdn.net/Dream_Lolita/article/details/82946121
今日推荐