题目太长,发个链接吧:题目
这是一道斯特林数:S(p,k) 表示p个数组成k个非空集合
S(p,k)的递推公式是:
S(p,k) = (p-1)*S(p-1,k) + S(p-1,k-1) ,1<= k <=p-1
边界条件:
S(p,p) = 1 ,p>=0
S(p,0) = 0 ,p>=1
递推关系的说明:
1. 考虑第p个物品,p可以单独构成一个非空集合,此时前p-1个物品构成k-1个非空的不可辨别的集合,方法数为S(p-1,k-1);
2. 也可以前p-1种物品构成k个非空的不可辨别的集合,第p个物品放入任意一个中,这样有(p-1)*S(p-1,k)种方法。
下面是代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
typedef long long LL;
LL fact[21]={1};
LL stela[21][21];
int main()
{
int n,t,k;
cin>>t;
for(int i=1;i<21;i++)
fact[i]=fact[i-1]*i;
for(int i=1;i<21;i++)
{
stela[i][0]=0;
stela[i][i]=1;
for(int j=1;j<i;j++)
{
stela[i][j]=stela[i-1][j-1]+stela[i-1][j]*(i-1);
}
}
while(t--)
{
cin>>n>>k;
LL sum=0;
for(int i=1;i<=k;i++)
sum+=stela[n][i]-stela[n-1][i-1];
printf("%.4lf\n",(double)sum/fact[n]);
}
return 0;
}