zoukankan      html  css  js  c++  java
  • AT2000 Leftmost Ball(计数dp+组合数学)

    传送门

    解题思路

      设(f[i][j])表示填了(i)个白色,(j)种彩色的方案数,那么显然(j<=i)。考虑这个的转移,首先可以填一个白色,就是(f[i][j]=f[i-1][j]*(n-i+1))。第二种情况是填一个彩色,这里有一点需要注意,不能直接用组合数,这样的话会有重复,我们可以强行安排一个顺序,这种颜色的第一个被变成了白色,第二个就直接跟在上一种彩色的后面,这样就可以做到不重不漏了,那么第二个转移就是(f[i][j]=f[i][j-1]*C(n*k-(i+(j-1)*(k-1)),k-2))

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    typedef long long LL;
    const int N=2005;
    const int MOD=1e9+7;
    
    int n,k,f[N][N],fac[N*N],inv[N*N];
    
    inline int fast_pow(int x,int y){
        int ret=1;
        for(;y;y>>=1){
            if(y&1) ret=(LL)ret*x%MOD;
            x=(LL)x*x%MOD;
        }	
        return ret;
    }
    
    inline int C(int x,int y){
        return 1ll*fac[x]*inv[y]%MOD*inv[x-y]%MOD;	
    }
    
    int main(){
        scanf("%d%d",&n,&k); if(k==1) {puts("1"); return 0;}
        f[0][0]=1; fac[0]=1;
        for(int i=1;i<=n*k;i++) fac[i]=1ll*fac[i-1]*i%MOD;
        inv[n*k]=fast_pow(fac[n*k],MOD-2);
        for(int i=n*k-1;~i;i--) inv[i]=1ll*inv[i+1]*(i+1)%MOD;
        for(int i=1;i<=n;i++)
            for(int j=0;j<=i;j++){
                if(j!=i) f[i][j]=1ll*f[i-1][j]*(n-i+1)%MOD;
                if(j!=0) (f[i][j]+=1ll*f[i][j-1]*C(n*k-(i+(j-1)*(k-1))-1,k-2)%MOD)%=MOD;
            }
        printf("%d
    ",f[n][n]);
        return 0;
    }	
    
  • 相关阅读:
    hiveserver2 with kerberos authentication
    python Basic usage
    python Quicksort demo
    Python HeapSort
    mrunit for wordcount demo
    CCDH证书
    Hadoop question list
    Hadoop Yarn core concepts
    Hadoop Resource
    Hadoop could not find or load main class
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/10398231.html
Copyright © 2011-2022 走看看