hdu 3625 Examining the Rooms —— 第一類斯特林數
阿新 • • 發佈:2018-12-04
題目:http://acm.hdu.edu.cn/showproblem.php?pid=3625
學習斯特林數:https://blog.csdn.net/qq_33229466/article/details/75042895
https://www.cnblogs.com/gzy-cjoier/p/8426987.html
http://www.cnblogs.com/zhouzhendong/p/Stirling-Number.html
關於這道題:
得到一把鑰匙後,可以連續開的門與鑰匙形成一個環;
所以破門次數就是環的個數;
但不能破1號門,也就是如果1號鑰匙在1號門裡,就無法進入了;
所以可行的情況都要減去1號門自己成環的情況,其實從遞推式可以看出來,直接減去 \( s[i-1][j-1] \) 即可;
20的階乘和範圍20的第一類斯特林數都大約正好達到 1e18,直接用 long long 即可。
程式碼如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; int const xn=25; int T,n,m; ll jc[xn],s[xn][xn]; int main() { jc[0]=1; for(int i=1;i<=20;i++)jc[i]=jc[i-1]*i; s[0][0]=1; for(int i=1;i<=20;i++) for(int j=1;j<=i;j++) s[i][j]=(i-1)*s[i-1][j]+s[i-1][j-1]; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); ll ans=0; for(int i=1;i<=m&&i<=n;i++)ans+=s[n][i]-s[n-1][i-1]; printf("%.4lf\n",1.0*ans/jc[n]); } return 0; }