本题是第一类斯特林数的典型题,若k把钥匙能全部打开的意思是,形成小于等于k个圆排列的数量,但注意1不能单独成排列,故在统计合法的排列数中应该减去。我们知道n把钥匙能形成的圆排列的数量是n!个,以此为分母即可。。。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll F[30],str[30][30];
int main()
{
F[0] = 1;
for(int i = 1; i <= 20; i++)
{
F[i] = i * F[i - 1];
}
for(int i = 1; i < 25; i++)
{
for(int j = 1; j < 25; j++)
{
if(i == j)
{
str[i][j] = 1;
}
else
{
str[i][j] = str[i - 1][j - 1] + (i - 1) * str[i - 1][j];
}
}
}
int T;
cin >> T;
while(T--)
{
ll sum = 0;
int n,k;
cin >> n >> k;
for(int j = 1; j <= k; j++)
{
sum += str[n][j] - str[n - 1][j - 1];
}
printf("%.4lf\n",1.0 * sum / F[n]);
}
return 0;
}