• 组合数例题


    1.糖果盒 nkoj 4052

    问题:
    何老板有很多颗相同的糖果,同时还有n个不同的糖果盒。何老板想把其中一些糖果放入这些盒子里,要求所有盒子里总的糖果数不超过m,问总共有多少种不同的方案?
    每个盒子的容量无限大,可以选择装糖,也可以不装。
    答案可能很大,mod p后在输出,p是一个素数。

    解:
    假设有k个糖果要装进n个糖果盒里面
    增设空格子 利用插板原理 答案为(c(n+m-1,{m-1}))

    所以不超过m的答案为(sum _{i=1}^{i=m} c(n+i-1,{i-1}))
    注意到(c(n ,0) =1) 所以可以换成(c(n+1,0))就递推就行了,
    我们有组合数公式 (C(N,M)=C(N-1,M)+C(N-1,M-1))
    于是就可以递推
    最终答案为(C(n+m,m))
    code:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long 
    ll n,m,p;
    ll ksm(ll a,ll b)
    {
    	ll ans=1;
    	while(b)
    	{
    		if(b&1) ans=(ans*a)%p;
    		a=(a*a)%p;
    		b>>=1;
    	}
    	return ans%p;
    }
    ll C(ll x,ll y)
    {
    	ll A=1,B=1;
    	for(int i=1;i<=y;i++)
    	{
    		A=(A*(x-y+i)%p)%p;
    		B=(B*(i)%p)%p;
    	}
    	return (A*ksm(B,p-2))%p;
    	
    }
    ll lucas(ll x,ll y)
    {
    	if(y==0) return 1;
    	return (C(x%p,y%p)*lucas(x/p,y/p))%p;
    }
    int main()
    {
    	cin>>n>>m>>p;
    	cout<<lucas(n+m,m)%p;
    }
    

    2.nkoj 4502 装糖果

    NK小卖部有m种不同口味的糖果出售。
    何老板委托你去买2*n颗糖装入两个盒子里,每个盒子里有一排n个方格,每个方格只能装1颗糖。何老板要求,两个盒子里不能有相同口味的糖果(同一个盒子里可以有口味相同的)。
    那么问题来了,总共有多少种方案呢?
    1≤n,m≤2000

    此题有两种做法

    1.
    首先 两个盒子就是两个变量
    我们想到先确定一个变量
    那么我们就枚举 第一个箱子确定装的(i)种糖果 那么第二个箱子就装的
    (m-i)种糖果 那么第二种箱子的方案数为 ((m-i)^n)
    讨论第一种箱子
    你就会想到是 将n个盒子划分成i个非空集合 这不就是第二类斯特林数吗???
    但是他有排列顺序 没关系 我们 times ({A_i^i}) 就行了(这里没有搞懂 准备明天再去问)
    答案就是(sum _{i=1}^{i=m-1} (C(m,i) imes f[n][i] imes(A_i^i) imes (m-i)^n))

    code:

    #include<iostream>
    #include<cstdio>
    #define mod 1000000007
    using namespace std;
    #define maxnn 2005
    #define ll long long
    using namespace std;
    ll f[maxnn][maxnn];
    ll n,m;
    ll ksm(ll a,ll b)
    {
        ll ans=1;
        while(b)
        {
            if(b&1) ans=(ans*a)%mod;
            a=(a*a)%mod;
            b>>=1;
        }
        return ans%mod;
    }
    ll C(ll n,ll m)
    {
        ll A=1,B=1;
        for(int i=1;i<=m;i++)
        {
            A=A*(n-m+i)%mod;
            B=B*(i)%mod;
        }
        return A*ksm(B,mod-2)%mod;
    }
    ll ksc(ll a,ll b)
    {
        ll ans=0;
        while(b)
        {
            if(b&1) ans=(ans+a)%mod;
            a=(a+a)%mod;
            b>>=1;
        }
        return ans%mod;
    }
    ll jie(ll n)
    {
        ll ans=1;
        for(int i=1;i<=n;i++)
        {
            ans=(ans*i)%mod;
        }
        return ans%mod;
    }
    int main()
    {
        cin>>n>>m;
        f[0][0]=1;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=i;j++)
            {
                f[i][j]=(f[i-1][j-1]+f[i-1][j]*j)%mod;
            }
        ll ans=0;
        for(int i=1;i<m;i++)
        {
            if(n>=i)
            ans=(ans+(ksc(ksc(ksc(C(m,i),f[n][i]),ksm(m-i,n)),jie(i)))%mod)%mod;
            
        }
        cout<<ans%mod;
    }
    

    2.
    假设f[i][j] 为前i个箱子装j种不同的糖果的方案

    (f[i][j]=f[i-1][j-1]*(m-j+1)+f[i-1][j]*j;)
    然后这里已经枚举了排列
    所以答案为
    (sum _{i=1}^{i=m-1} (f[n][i] imes (m-i)^n))

    刀剑映出了战士的心。而我的心,漆黑且残破
  • 相关阅读:
    【数学】杜教筛
    【数学】【多项式】多项式求逆
    【数学】求导
    【数学】【多项式】快速数论变换(NTT)
    【数学】【多项式】快速傅里叶变换(FFT)
    WC2021 Day3 笔记
    网络流
    $DP$ 重修
    数学基础 5
    数学基础 3
  • 原文地址:https://www.cnblogs.com/OIEREDSION/p/11565355.html
Copyright © 2020-2023  润新知