Rhyme Schemes
Time Limit: 1000MS | Memory Limit: 10000K | |||
Total Submissions: 1175 | Accepted: 645 | Special Judge |
Description
The rhyme scheme for a poem (or stanza of a longer poem) tells which lines of the poem rhyme with which other lines. For example, a limerick such as If computers that you build are quantum
Then spies of all factions will want 'em
Our codes will all fail
And they'll read our email
`Til we've crypto that's quantum and daunt 'em
Jennifer and Peter Shor (http://www.research.att.com/~shor/notapoet.html)
Has a rhyme scheme of aabba, indicating that the first, second and fifth lines rhyme and the third and fourth lines rhyme.
For a poem or stanza of four lines, there are 15 possible rhyme schemes:
aaaa, aaab, aaba, aabb, aabc, abaa, abab, abac, abba, abbb, abbc, abca, a bcb, abcc, and abcd.
Write a program to compute the number of rhyme schemes for a poem or stanza of N lines where N is an input value.
Then spies of all factions will want 'em
Our codes will all fail
And they'll read our email
`Til we've crypto that's quantum and daunt 'em
Jennifer and Peter Shor (http://www.research.att.com/~shor/notapoet.html)
Has a rhyme scheme of aabba, indicating that the first, second and fifth lines rhyme and the third and fourth lines rhyme.
For a poem or stanza of four lines, there are 15 possible rhyme schemes:
aaaa, aaab, aaba, aabb, aabc, abaa, abab, abac, abba, abbb, abbc, abca, a bcb, abcc, and abcd.
Write a program to compute the number of rhyme schemes for a poem or stanza of N lines where N is an input value.
Input
Input will consist of a sequence of integers N, one per line, ending with a 0 (zero) to indicate the end of the data. N is the number of lines in a poem.
Output
For each input integer N, your program should output the value of N, followed by a space, followed by the number of rhyme schemes for a poem with N lines as a decimal integer with at least 12 correct significant digits (use double precision floating point for your computations).
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).