hdu 3625 Examining the Rooms 第一类stirling数

斯特林数的第一类应用

题意就是 求n个元素分成k个环排列的数目。

递推公式是:

s( n , 0 ) = 0;

s( 1 ,1 ) =1;

s( n , k ) = s( n- 1 , k-1 )+ (n-1)*s( n-1 , k);

公式的意思是 :

 当 n-1个 形成了 k-1 个 环时,第n个只能形成单环。 方案数 是  s( n -1 , k -1 )

当n-1个形成了 k个环时,这 k 个环中 共有 n-1 个位置可以放, 则  方案数 是  s( n-1 , k ) *( n -1);


此题中 第一个门 只能用钥匙 , 也就是说  1 不可以形成单环。 则  n 个元素形成 k 个环的 方案数 是  s(n, k) - s( n -1 , k-1);


#include <iostream>
#include <cstring>
#include <cstdio>

using namespace std;
#define LL long long
LL s[25][25];
void init(){
        memset(s,0,sizeof(s));
        s[1][1] = 1;
        for(int i=2;i<=20;i++){
            for(int k =1;k<=i;k++){
                s[i][k] = s[i-1][k-1] + (i-1)*s[i-1][k];
             //   cout << s[i][k] << " ";
            }
          //  cout << endl;
        }
}
int n, k ;
void solve(){
    LL sum =0 ;
    for(int i=1;i<=k;i++){
        sum += s[n][i];
    }
    for(int i =1;i<= k-1;i++){
        sum -= s[n-1][i];
    }
    LL p = 1;
    for(int i=1;i<=n;i++){
        p *= i;
    }
    double ans = sum / (double)p;
    printf("%.4f\n",ans);
    
}

int main() {
    int t ;
    cin >> t;
    init();
    while(t-- ){
        scanf("%d%d",&n,&k);
        solve();   
       
    }
    return 0;
}


你可能感兴趣的:(hdu 3625 Examining the Rooms 第一类stirling数)