题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3625
组合数学。
第一次听说斯特灵数,定义参见维基百科:https://zh.wikipedia.org/wiki/%E6%96%AF%E7%89%B9%E7%81%B5%E6%95%B0
N个元素,要组成K个环排列。
有几个公式:
S(N,0)=0;
S(N,N)=1;
S(0,0)=0;
S(N,K)=S(N-1,K-1)+S(N-1,K)*(N-1);
有因为题目特别规定1不能单独成环,所以要把1单独成环的组合去掉。即S(N,K)-S(N-1,K-1)才是构成k个环的方法数。知道这些打表过就可以了。
参考博客:http://www.cnblogs.com/nanke/archive/2011/09/07/2170290.html
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
using namespace std;
typedef long long ll;
ll fac[21] = {1};
ll stirling[21][21];
int main() {
int i, j;
for(i = 1; i <= 20; i++) {
fac[i] = fac[i - 1] * i;
}
for(i = 1; i <= 20; i++) {
stirling[i][0] = 0;
stirling[i][i] = 1;
for(j = 1; j <= 20; j++) {
if(i != j) stirling[i][j] = stirling[i - 1][j - 1] + (i - 1) * stirling[i - 1][j];
}
}
int t, n, k;
scanf("%d",&t);
while(t--) {
scanf("%d %d", &n, &k);
ll sum = 0; //因为n>1, k>0的,所以不必特判
for(i = 1; i <= k; i++) { //只要有小于等于k个环都能满足条件
sum += stirling[n][i] - stirling[n - 1][i - 1];
}
printf("%.4lf\n",(double)sum/fac[n]);
}
return 0;
}