Gym

来源:互联网 发布:js 增加option 编辑:程序博客网 时间:2024/06/07 09:21

题目链接:http://codeforces.com/gym/101147/problem/G



题解:

第二类斯特林数:将n个不同的球放入m个无差别的盒子中,要求盒子非空,有几种方案?

假设要把n+1个元素分成m个集合则分析如下:
(1)如果n个元素构成了m-1个集合,那么第n+1个元素单独构成一个集合。方案数
  
(2)如果n个元素已经构成了m个集合,将第n+1个元素插入到任意一个集合。方案数 m*S(n,m) 。
综合两种情况得:

几种变形:

第二类Stirling数主要是用于解决组合数学中的几类放球模型。主要是针对于球之前有区别的放球模型:
(1)n个不同的球,放入m个无区别的盒子,不允许盒子为空。
方案数:
  
。这个跟第二类Stirling数的定义一致。
(2)n个不同的球,放入m个有区别的盒子,不允许盒子为空。
方案数:
  
。因盒子有区别,乘上盒子的排列即可。
(3)n个不同的球,放入m个无区别的盒子,允许盒子为空。
方案数:
  
。枚举非空盒的数目便可。
(4)n个不同的球,放入m个有区别的盒子,允许盒子为空。
①方案数:
  
。同样可以枚举非空盒的数目,注意到盒子有区别,乘上一个排列系数。
②既然允许盒子为空,且盒子间有区别,那么对于每个球有m中选择,每个球相互独立。有方案数:
  



代码如下:

#include <iostream>#include <cstdio>#include <cstring>#include <cstdlib>#include <string>#include <vector>#include <map>#include <set>#include <queue>#include <sstream>#include <algorithm>using namespace std;#define pb push_back#define mp make_pair#define ms(a, b)  memset((a), (b), sizeof(a))//#define LOCAL#define eps 0.0000001#define LNF (1<<60)typedef long long LL;const int inf = 0x3f3f3f3f;const int maxn = 100000+10;const int mod = 1e9+7;LL dp[1005][1005];void solve(){    ms(dp,0);    for(int i = 1; i<1005; i++)//先假设集合无区别    {        dp[i][0] = 0; dp[i][i] = 1;        for(int j = 1; j<i; j++)            dp[i][j] = (dp[i-1][j]*j + dp[i-1][j-1])%mod;    }    LL t = 1;    for(int j = 1; j<1005; j++)//因为集合有区别,所以要乘上阶乘    {        t = (t*j)%mod;        for(int i = j; i<1005; i++)            dp[i][j] = (dp[i][j]*t)%mod;    }    int T,n,k;    scanf("%d",&T);    while(T--)    {        scanf("%d%d",&n,&k);        if(n<k)//当n<k时,不要直接输出dp[n][k], 因为k<=1e6,会溢出。        {            puts("0");            continue;        }        printf("%lld\n",dp[n][k]);    }}int main(){    #ifdef LOCAL    freopen("galactic.in", "r", stdin);    //  freopen("output.txt", "w", stdout);    #endif // LOCAL    solve();//    int T;//    scanf("%d", &T);//    while(T--){//        solve();//   }    return 0;}


0 0