HDU 3625 Examining the Rooms (第一类斯特灵数,组合数学)

题目链接: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;
}



你可能感兴趣的:(HDU 3625 Examining the Rooms (第一类斯特灵数,组合数学))