zoukankan      html  css  js  c++  java
  • H

    AT原题

    以前做过,现在来整理思路

    因为白球是一种特殊的球只会存在于一种颜色所有球的最前面,所以我们考虑把白球和其他球分开来

    (dp[i][j])表示我们已经放置了(i)个白球和(j)种颜色的球的方案数,显然必须满足(j leq i)

    转移有两种
    1.上一次放了一个白球
    2.上一次放了一种颜色的球,即放了(k-1)个相同颜色的球

    放白球必须尽量靠前,为了避免重复,我们把白球放在第一个空位上。
    如果不是在第一个空位上,而是在任意空位上,则有可能导致某个白球不是某种颜色球的第一个,
    而且在DP时不同时候放的白球可能会导致最终结果重复。

    放白球的贡献为(dp[i-1][j])

    放有颜色的球,首先要从(n - j + 1)种颜色中选一个
    然后我们剩下了(n * k - i - (j - 1)*(k - 1))个空位,我们需要从中选(k - 1)个空位放我们的球,
    但是贡献并不是(C_{n * k - i - (j - 1)*(k - 1)}^{k-1}),而是(C_{n * k - i - (j - 1)*(k - 1)-1}^{k-2})
    原因还是重复,如果我们不取出一个球,把第一个空位占掉,那么对于任意两次放有颜色球的操作,其结果可能是一样的,但是计算会重复
    假设一下,我有四个空位,每次放两个有颜色的球,一共放两次。
    第一次,选红色, 放2,3位; 第二次,选蓝色,放1,4位

    第一次,选蓝色, 放1,4位; 第二次,选红色,放2,3位
    是一样的,这就是不把第一个空位占掉导致的重复

    贡献为((n - j + 1) * C_{n * k - i - (j - 1)*(k - 1)-1}^{k-2})

    注意k=1!!!

    
    #include<bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    const int mod = 1e9 + 7;
    
    int n,k;
    int dp[2050][2050];
    
    int fac[4000050],inv[4000050];
    int ksm(int x,int y){
        int z = 1;
        while(y){
            if(y & 1) z = z * x % mod;
            y >>= 1;
            x = x * x % mod;
        }
        return z;
    }
    int C(int n,int m){
        if(n < m || m < 0) return 0;
        if(n == m || m == 0) return 1;
        return (fac[n] * inv[m] % mod) * inv[n - m] % mod;
    }
    
    signed main(){
        scanf("%lld%lld",&n,&k);
        
        fac[0] = 1;
        for(int i = 1; i <= 4000000; ++ i) fac[i] = fac[i - 1] * i % mod;
        inv[4000000] = ksm(fac[4000000],mod - 2);
        for(int i = 3999999; i >= 0; -- i) inv[i] = inv[i + 1] * (i + 1) % mod;
        
        if(k == 1) { puts("1"); return 0; } 
        
        dp[0][0] = 1;
        for(int i = 1; i <= n; ++ i){
            dp[i][0] = 1;
            for(int j = 1; j <= i; ++ j){
                dp[i][j] = (dp[i - 1][j] + dp[i][j - 1] * C(n * k - i - (j - 1) * (k - 1) - 1, k - 2) % mod * (n - j + 1) % mod ) % mod; 
            }
        }
        
        printf("%lld
    ",dp[n][n]);
        return 0;
    }
    
    
  • 相关阅读:
    算法与数据结构9
    算法与数据结构8
    数据结构与算法7
    数据结构与算法6
    计算机视觉(七)
    计算机视觉(六)
    计算机视觉(五)
    vscode 创建java项目
    vue 访问API接口
    vscode+vue 框架搭建
  • 原文地址:https://www.cnblogs.com/zzhzzh123/p/13344555.html
Copyright © 2011-2022 走看看