题意: 有n行诗,每行都有其韵律。
问题:n行诗存在的韵律组合数。
思路:第二类Stirling数是把个元素放入k个等价类的方法数目(每个等价类都不能为空)。(摘自维基百科,稍有修改)
注意到此题的'行数'>='韵律数',可以把'行数'抽象为n个元素,'韵律数'抽象为k个等价类.
所求即为:把n行放入k个‘韵律’中的方法数( 其中:1=< k <=n )。
状态转移方程:
F[ i, j ] = F[ i-1, j-1 ] + F[ i-1, j ] * j
F[ 1, j ] = 0 (j > 1) 表示:‘韵律数’超过'行数'时,一定会存在空'韵律'.
F[ i, 1 ] = 1 (i >= 1)表示:只存在一种‘韵律’时,把i行放入这一个‘韵律’中的方法数始终为1.
#include<iostream>
#include<cstdio>
using namespace std;
// 变量
int n; // 人数
double F[101][101]; // F[i][j]:表示把i个人装进j个盒子中的方法数(每个盒子都非空)
void DP()
{
// init
for( int j = 1; j <= 100; ++ j )
F[1][j] = 0;
for( int i = 1; i <= 100; ++ i )
F[i][1] = 1;
// dp
for( int i = 2; i <= 100; ++ i )
for( int j = 2; j <= i; ++ j )
F[i][j] = F[i-1][j-1] + F[i-1][j]*j;
}
int main()
{
DP();
while( cin >> n && n )
{
double res = 0;
for( int i = 1; i <= n; ++ i )
res += F[n][i];
printf( "%d %.0f\n", n, res );
}
return 0;
}