山大工大联谊1007 combinatorial mathematics once more 【斯特灵数,贝尔数】

来源:互联网 发布:centos中文man手册 编辑:程序博客网 时间:2024/04/30 22:39

1007 combinatorial mathematics once more 

description
如果你对组合数学有所涉猎,你一定会对组合划分非常熟悉,那么问题来了:现在给你一个数集S的大小n,请告诉我将它划分为集合的方法总数ans是多少?

input
多组数据输入,每组输入有一个n(n<=5000)

output
首先请输出Case #x,表示当前为第x个样例,然后输出ans的值,也许答案会很大,所以请输出ans%(1e9+7)

sample input
3

sample  output

Case #1: 5

Hints:
n=3,ans=5,
具体方法有如下几种:
{{a}, {b}, {c}}
{{a}, {b, c}}
{{b}, {a, c}}
{{c}, {a, b}}
{{a, b, c}}

题意:  n个物品 可以都多少种不为空的划分。

分析:    sigma(S(n,i)) i=1->n,其中S(n,i)为第二类斯特林数。亦或者B(i),其中B表示贝尔数。  详见代码后。

#include<iostream>#include<cstdio>#include<cstring>#include<ctime>#include<algorithm>#include <map>#include <queue>#include <set>using namespace std;//2015.3.29long long s[5000][5000];long long b[5000];int n;void Bell(int n){    for(int i=1;i<=n;i++)    {        s[i][0]=0;        s[i][i]=1;        b[i]=1;        for(int j=i-1;j>=1;j--)        {            s[i][j]=(s[i-1][j-1]+j*(s[i-1][j]))%1000000007;        }    }    for(int i=1;i<=5000;i++)    {        b[i]=0;        for(int j=0;j<=i;j++)        {            b[i]=(b[i]+s[i][j])%1000000007;        }    }}int main(){    int q=1;    Bell(5000);    while(true)    {        cin>>n;        printf("Case #%d:%I64d",q,b[n]);    }    return 0;}

HDU 2512 一卡通大冒险(斯特灵数,贝尔数)

转载请注明出处,谢谢http://blog.csdn.net/acm_cxlove/article/details/7854526       by---cxlove

题目:将N张卡分成若干个集合,集合不为空,有多少种分法。

http://acm.hdu.edu.cn/showproblem.php?pid=2512

显然集合个数为1,2……n。也就是将N张卡放到i个集合内。

这类组合问题用第二类斯特灵数可以解决

S(P,K)=S(P-1,K-1)+K*S(P-1,K);表示P个元素放入K个不可区分的集合中而且集合不为空的划分个数。

那么问题的解为sigma(S(P,i))  (P=>i>=1) 这个和称为bell数。

Bell数是将P个元素集合分到非空且不可区分例子的划分个数。详见组合数学

[cpp] view plaincopy
  1. #include<iostream>  
  2. #include<cmath>  
  3. #include<cstdio>  
  4. #include<cstring>  
  5. #define LL long long  
  6. #define eps 1e-7  
  7. #define MOD 1000  
  8. using namespace std;  
  9. int stir2[2005][2005]={1};  
  10. int bell[2005];  
  11. int main(){  
  12.     for(int i=1;i<=2000;i++){  
  13.         stir2[i][0]=0;  
  14.         stir2[i][i]=1;  
  15.         for(int j=1;j<i;j++)  
  16.             stir2[i][j]=(stir2[i-1][j-1]+j*stir2[i-1][j])%MOD;  
  17.     }  
  18.     for(int i=1;i<=2000;i++){  
  19.         bell[i]=0;  
  20.         for(int j=0;j<=i;j++)  
  21.             bell[i]=(bell[i]+stir2[i][j])%MOD;  
  22.     }  
  23.     int n,t;  
  24.     cin>>t;  
  25.     while(t--){  
  26.         cin>>n;  
  27.         cout<<bell[n]<<endl;  
  28.     }  
  29.     return 0;  
  30. }  


0 0
原创粉丝点击