zoukankan      html  css  js  c++  java
  • BZOJ1004: [HNOI2008]Cards

    三维01背包算出在每一个置换下不变的染色方案数,Burnside引理计算答案。

    PS:数据太水所以只算恒等置换也是可以过的。

    #include<bits/stdc++.h>
    using namespace std;
    int n,m,p,x,y,z;
    bool u[61];
    int f[21][21][21],s[61],v[61];
    int power(int u,int v){
    	int d=1;
    	for(;v;v>>=1){
    		if(v&1)
    			d=d*u%p;
    		u=u*u%p;
    	}
    	return d;
    }
    void add(int& u,int v){
    	u=(u+v)%p;
    }
    int main(){
    	scanf("%d%d%d%d%d",&x,&y,&z,&m,&p);
    	n=x+y+z;
    	int ans=1;
    	for(int i=1;i<=n;++i)
    		ans=ans*i%p;
    	for(int i=1;i<=x;++i)
    		ans=ans*power(i,p-2)%p;
    	for(int i=1;i<=y;++i)
    		ans=ans*power(i,p-2)%p;
    	for(int i=1;i<=z;++i)
    		ans=ans*power(i,p-2)%p;
    	for(int t=0;t!=m;++t){
    		for(int i=1;i<=n;++i)
    			scanf("%d",s+i);
    		memset(u,0,sizeof u);
    		int cnt=0;
    		for(int i=1;i<=n;++i)
    			if(!u[i]){
    				int k=u[i]=1;
    				for(int j=s[i];j!=i;j=s[j])
    					k+=u[j]=1;
    				v[cnt++]=k;
    			}
    		memset(f,0,sizeof f);
    		f[0][0][0]=1;
    		for(int a=0;a!=cnt;++a)
    			for(int i=x;~i;--i)
    				for(int j=y;~j;--j)
    					for(int k=z;~k;--k){
    						if(i>=v[a])
    							add(f[i][j][k],f[i-v[a]][j][k]);
    						if(j>=v[a])
    							add(f[i][j][k],f[i][j-v[a]][k]);
    						if(k>=v[a])
    							add(f[i][j][k],f[i][j][k-v[a]]);
    					}
    		add(ans,f[x][y][z]);
    	}
    	printf("%d
    ",ans*power(m+1,p-2)%p);
    }
    
  • 相关阅读:
    Codeforces610b
    Codeforces597A
    Timus1014(贪心算法)
    一般贪心
    优先队列问题(此题来源哈尔滨理工大学VJ)
    POJ2551Dungeon Master
    LightOJ 1140: How Many Zeroes? (数位DP)
    HDU 2089:不要62(数位DP)
    HDU 4722:Good Numbers(数位DP)
    HDU 3709: Balanced Number (数位DP)
  • 原文地址:https://www.cnblogs.com/f321dd/p/5495898.html
Copyright © 2011-2022 走看看