zoukankan      html  css  js  c++  java
  • Leftmost Ball

    题目链接:Click here

    Solution:

    我们把问题转化一下,改成可以放白球和其他颜色的球

    那么对于一种合法的方案,显然有它的任意一个前缀的白球数大于等于其他颜色数

    那么,我们考虑设(f[i][j])表示已经放了(i)个白球,刚好放完了(j)种颜色的方案数

    考虑有两种转移,一种是我们再放一个白球,或者再加入一种颜色

    这里我们钦定接下来放的第一个球一定在第一个空缺的位置,否则就会算重

    那么转移就是这样的:

    [f[i][j]=f[i-1][j]+f[i][j-1] imes {(k-1) imes (n-j+1)+n-i-1 choose k-2} ]

    需要注意的是,当(k=1)时,我们需要给出特判,并且我们在(dp)时是没有考虑颜色的排列顺序的,所以最后要乘上阶乘

    Code:

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=2e3+11;
    const int M=4e6+11;
    const int mod=1e9+7;
    int n,k,f[N][N],fac[M],ifac[M];
    int read(){
        int x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
        while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
        return x*f;
    }
    int qpow(int a,int b){
        int re=1;
        while(b){
            if(b&1) re=(re*a)%mod;
            b>>=1;a=a*a%mod;
        }return re;
    }
    int C(int a,int b){
        if(a<b) return 0;
        return fac[a]*ifac[b]%mod*ifac[a-b]%mod;
    }
    signed main(){
        n=read(),k=read();
        if(k==1) return puts("1"),0;
        fac[0]=1;ifac[0]=1;f[0][0]=1;
        for(int i=1;i<=n*k;i++) fac[i]=fac[i-1]*i%mod;
        ifac[n*k]=qpow(fac[n*k],mod-2);
        for(int i=n*k-1;i;i--) ifac[i]=ifac[i+1]*(i+1)%mod;
        for(int i=1;i<=n;i++)
            for(int j=0;j<=i;j++){
                if(i>j) f[i][j]+=f[i-1][j];
                f[i][j]=(f[i][j]+f[i][j-1]*C((n-j+1)*(k-1)+n-i-1,k-2)%mod)%mod;
            }
        printf("%lld
    ",f[n][n]*fac[n]%mod);
        return 0;
    }
    
  • 相关阅读:
    win7 下如何安装 Microsoft Web Application Stress Tool
    [译文]casperjs的API-mouse模块
    【性能测试】jmeter的坑(1)——如何在多网卡情况下正确连接
    [性能分析]端口限制
    [性能分析]linux文件描述符
    python 对mongodb进行压力测试
    常用jar包信息
    Basic Grammer
    Maven 知识汇总
    【Linux】Linux常用命令
  • 原文地址:https://www.cnblogs.com/NLDQY/p/12214807.html
Copyright © 2011-2022 走看看