hdu 3625 Examining the Rooms(第一類斯特林數)
阿新 • • 發佈:2018-12-05
解題思路
首先門其實形成了若干個環,每次可以將這個環內的所有門都開啟。這樣就可以想到第一類斯特林數,設\(f[i][j]\)表示把前\(i\)個數字劃分成\(j\)個環的方案,\(f[i][j]=(i-1)f[i-1][j]+f[i-1][j-1]\)。然後注意還要把不能炸第一個這個條件考慮到。最後的答案為\(\dfrac{\sum\limits_{i=1}^k f[n][i]-f[n-1][i-1]}{n!}\)。
程式碼
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 22; typedef long long LL; inline int rd(){ int x=0,f=1;char ch=getchar(); while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar(); return f?x:-x; } int T,n,k; LL ans,fac[MAXN],f[MAXN][MAXN]; int main(){ fac[1]=1;f[0][0]=1; for(int i=2;i<=20;i++) fac[i]=fac[i-1]*i; for(int i=1;i<=20;i++) for(int j=1;j<=i;j++) f[i][j]=(i-1)*f[i-1][j]+f[i-1][j-1]; T=rd(); while(T--){ n=rd(),k=rd();ans=0; for(int i=1;i<=k;i++) ans+=f[n][i]-f[n-1][i-1]; printf("%.4lf\n",(double)ans/fac[n]); } return 0; }