Time Limit: 1000MS | Memory Limit: 10000K | |||
Total Submissions: 1175 | Accepted: 645 | Special Judge |
Description
Input
Output
Sample Input
1 2 3 4 20 30 10 0
Sample Output
1 1 2 2 3 5 4 15 20 51724158235372 30 846749014511809120000000 10 115975
Source
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> using namespace std; #define MAXN 100 double f[MAXN][MAXN]; double dfs(int high, int len){ int i; double ret; if (len == 1) return high; if (f[len][high] >= 0) return f[len][high]; for (i = 1, ret = 0; i <= high; i++){ ret += dfs(max(high, i + 1), len - 1); } return f[len][high] = ret; } int main(){ int i, j, n; for (i = 0; i < MAXN; i++) for (j = 0; j < MAXN; j++) f[i][j] = -1; while(scanf("%d", &n), n != 0){ printf("%d %.0f\n", n, dfs(1, n)); } return 0; } /* 问题:将n个点分成一个个集合,问分法数。 例如,n=4, aaab, aaba, abcd, 是不同分法, 但是aaab = bbba, abcd = abdc 从输入样例可以看出, abdc这种写法是不合法的,或者说是没必要考虑 类似数位DP做的 数学上,叫第二类Stirling数 S(n,k) = k*S(n-1,k) + S(n-1,k-1) 状态: 前n个点,分成了k个集合 奇怪的,n=50以后,结果为0,再大点就RE了... */
补充:
Bell数
又称为贝尔数,是以埃里克·坦普尔·贝尔(Eric Temple Bell)为名的。
B(n)是包含n个元素的集合的划分方法的数目。 B(0) = 1, B(1) = 1, B(2) = 2, B(3) = 5, B(4) = 15, B(5) = 52, B(6) = 203,... 递推公式为, B(0) = 1, B(n+1) = Sum(0,n) C(n,k)B(k). n = 1,2,... 其中,Sum(0,n)表示对k从0到n求和,C(n,k) = n!/[k!(n-k)!] ------------------------- Stirling数
又称为斯特灵数,在组合数学,Stirling数可指两类数,都是由18世纪数学家James Stirling提出的。 第一类Stirling数是有正负的,其绝对值是包含n个元素的集合分作k个环排列的方法数目。 递推公式为, S(n,0) = 0, S(1,1) = 1. S(n+1,k) = S(n,k-1) + nS(n,k)。 第二类Stirling数是把包含n个元素的集合划分为正好k个非空子集的方法的数目。 递推公式为, S(n,n) = S(n,1) = 1, S(n,k) = S(n-1,k-1) + kS(n-1,k). ------------- 每个贝尔数都是"第二类Stirling数"的和。 B(n) = Sum(1,n) S(n,k).