题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2512
题目大意:
有N张卡,将N张卡分成若干不同的集合,集合不能为空。问:总共有多少种分法。
思路:
参考博文:http://blog.csdn.net/acm_cxlove/article/details/7857671
集合的个数可以为1、2、3、…、N。问题就变为了把N张卡放到i个集合中。
这时候个组合问题,可以用第二类斯特灵数解决。
S(P,K) = S(P-1,K-1) + K*S(P-1,K);
表示P个元素放入K个不可区分的集合中而集合不为空的划分个数。
问题的解就为: ΣS(P,i),(1 <= i <= P)。这个数就成为贝尔数。
贝尔数是将P个元素集合分到非空且不可区分例子的划分个数。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
int stir[2010][2010],Bell[2010];
int main()
{
for(int i = 1; i <= 2000; ++i)
stir[i][1] = stir[i][i] = 1;
for(int i = 2; i <= 2000; ++i)
{
for(int j = 2; j <= i; ++j)
stir[i][j] = (stir[i-1][j-1] + stir[i-1][j]*j)%1000;
}
for(int i = 1; i <= 2000; ++i)
for(int j = 1; j <= i; ++j)
Bell[i] = (Bell[i] + stir[i][j]) % 1000;
int N,T;
cin >> T;
while(T--)
{
cin >> N;
cout << Bell[N] << endl;
}
return 0;
}
原文:http://blog.csdn.net/lianai911/article/details/44893435