1. 程式人生 > >hdu 3625 Examining the Rooms —— 第一類斯特林數

hdu 3625 Examining the Rooms —— 第一類斯特林數

題目: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; }