(Aleppo + HAIST + SVU + Private) CPC 2022 J补充

思路在代码中写了:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define int long long
const int maxn = 4e3 + 10;
const int mod = 1e9 + 7;
int cnt[maxn], fact[maxn], infact[maxn],inv[maxn];//求C
int dp[maxn];//dp[i]代表前i个盒子装k个球方案数和
int q_pow(int a, int b)
{
    int ans = 1;
    while (b)
    {
        if (b & 1)
        {
            ans = ans * a%mod;
        }
        b >>= 1;
        a = a * a%mod;
    }
    return ans % mod;
}
void init()
{
    fact[0] = infact[0] = 1;
    for (int i = 1; i < maxn; i++)
        fact[i] = fact[i - 1] * i%mod;
    infact[maxn - 1] = q_pow(fact[maxn - 1], mod - 2);
    for (int i = maxn - 2; i; i--)
    {
        infact[i] = infact[i + 1] * (i + 1) % mod;
    }
}
int C(int a, int b)
{
    if (a < b)
        return 0;
    return fact[a]*infact[b]%mod*infact[a - b] % mod;
}
void solve(){
    int n, k;
    cin >> n >> k;
    memset(cnt, 0, sizeof cnt);
    int x;
    for (int i = 1; i <= n; i++){
        cin >> x;
        cnt[x]++;
    }
    for (int i = 1; i <=k; i++){
        int tmp = 1;
        for (int j = 1; j <= n; j++){
            if (cnt[j]){
                tmp = tmp * C(i - 1 + cnt[j],cnt[j])%mod;//这个组合数表示有n个相同的球,k个不同的盒子,把n个球放到盒子里,盒子允许为空    
//为什么此时不是利用n个球,k个不同的盒子,不能为空呢,因为此时我们可以发现,对于一种球,可能其只能填一些地方,其他的盒子一定为空
//我们在处理完后会发现此时有一些可能是有盒子是完全为空的,所以有了接下来的删除操作
//对于该删除操作,我们可以理解为将n个球全部塞在j个盒子中的可能减去
            }
        }
        for (int j = 1; j < i; j++)
            tmp =(tmp-dp[i-j] * C(i, j))%mod;
        dp[i] = tmp;
    }
    cout << (dp[k] % mod+mod)%mod << endl;
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    int t;
    init();
    cin >> t;
    while (t--)
        solve();

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值