这道题其实就是斯特林数,找不同的集合,一共有多少中组法,递推式就是dp[n][k] = dp[n - 1][k - 1] + k * dp[n - 1][k];
这个式子可以这么解释,dp[n][k]就是总数为n分成k个集合一共有多少种, 它就有两种情况一种是第一个自己一个集合(也就是他自己一堆), 那么这种情况下的种类就是dp[n - 1][k - 1],就是剩下的n -1 个有k -1堆, 还有一种就是先把第一个拿出来,然后将剩下的n- 1个分成k个集合, 然后再把第一个随便放入一个, 但是它可以有k中放法,所以就是k * dp[n - 1][k];
代码如下:
#include<iostream>
#include <stdio.h> using namespace std;
int dp[][];
int main()
{
for (int i = ; i < ; i++)
dp[i][] = , dp[i][i] = ;
dp[][] = ;
dp[][] = ;
dp[][] = ;
for (int i = ; i < ; i++)
{
for (int j = ; j < i; j++)
{
dp[i][j] = (dp[i - ][j - ] + j * dp[i - ][j]) % ;
}
}
int n;
scanf("%d", &n);
while (n--)
{
int x;
scanf("%d", &x);
int res = ;
for (int i = ; i <= x; i++)
{
res += dp[x][i];
}
res %= ;
printf("%d\n", res);
} return ;
}