zoukankan      html  css  js  c++  java
  • CF140E

    (m)种颜色,(n)层,给每层(l_i)个位置涂色,要求相邻位置颜色不同,相邻层数颜色集合也不能相同,求方案数

    考虑在一行内彩球的方案数,(g[i][j])表示一共(i)个球串成一行,共用(j)种颜色的方案数

    类似最小表示法简化计数,强制令其有序,实际方案数为(g[i][j]*j!)

    若前(i-1)个球使用了(j-1)种颜色,则第(i)个球必然使用了第(j)种颜色;若前(i-1)个球已使用了(j)种颜色,则第(i)个球使用的颜色必须与第(i-1)个球不同,所以有((j-1))种方案

    (g[i][j]=g[i-1][j-1]+(j-1)g[i-1][j])

    考虑行与行的影响

    (f[i][j])表示前(i)层恰用了(j)种颜色

    若不考虑两层之间颜色集合需不同

    (f[i][j]=A_m^j*g[l[i]][j]*sum f[i-1][k])

    减去不合法

    (f[i][j]=A_m^j*g[l[i]][j]*sum f[i-1][k]-f[i-1][j]*g[l[i]][j]*j!)

    ll n,m,mod,maxx,l[2000005],A[M],fac[M],f[5005][5005],g[2][5010];
    int main(){
    	scanf("%lld%lld%lld",&n,&m,&mod); fac[0] = A[0] = f[0][0] = 1;
    	for(int i = 1;i <= n;++i) l[i] = read(),maxx = max(maxx,l[i]);
    	for(int i = 1;i <= maxx;++i) A[i] = A[i-1] * (m-i+1) % mod;
    	for(int i = 1;i <= maxx;++i) fac[i] = fac[i-1] * i % mod;
    	for(int i = 1;i <= maxx;++i)
    		for(int j = 1;j <= i && j <= m;++j)
    			f[i][j] = (f[i-1][j-1] + f[i-1][j]*(j-1)) % mod;
    	ll ans = 1,sum = 0;
    	for(int i = 1;i <= n;++i){
    		for(int j = 1;j <= l[i];++j){
    			ll tmp = (A[j]*ans - g[i&1^1][j]*fac[j]) % mod;
    			g[i & 1][j] = f[l[i]][j] * tmp % mod;
    			sum += g[i & 1][j];
    		}
    		ans = (sum % mod + mod) % mod; sum = 0;
    		memset(g[i&1^1],0,sizeof(g[0]));
    	}
    	printf("%lld",ans);
    }
    
  • 相关阅读:
    Parrot虚拟机
    JAVA数据结构二叉排序树
    mysql基本操作
    ruby数组操作
    JAVA核心技术之球体碰撞多线程版
    JAVA数据结构选择排序
    JAVA的线程让步
    Perl 与数学:一份快速参考
    科学计算软件包python(x,y)简介
    JAVA数据结构解析数学表达式
  • 原文地址:https://www.cnblogs.com/shikeyu/p/13830172.html
Copyright © 2011-2022 走看看