zoukankan      html  css  js  c++  java
  • hdu 3625 Examining the Rooms 轮换斯特林数

    题目大意

    n个房间对应n把钥匙
    每个房间的钥匙随机放在某个房间内,概率相同。
    有K次炸门的机会,求能进入所有房间的概率
    一号门不给你炸

    分析

    我们设(key_i)为第i间房里的钥匙是哪把
    视作房间i向房间(key_i)连了一条有向边
    这相当于n个点n条边,且每个点出度入度都为1
    就是m个环,就是置换嘛
    相当于第一类斯特林数(left [egin{matrix} n\ m end{matrix} ight])

    做法

    一个环中炸掉一个门就可以开环中所有的门
    问题转化为求环的数量(le k)的方案数
    由于1不能单独在一个环中(因为不能炸)

    [sumlimits_{k=1}^nleft( left [egin{matrix} n\ k end{matrix} ight]-left [egin{matrix} n-1\ k-1 end{matrix} ight] ight) ]

    (1单独在一个环中则剩下n-1个点和k-1个环)

    solution

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cctype>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    typedef long long LL;
    typedef double db;
    const int M=23;
    
    int rd(){
    	int x=0;bool f=1;char c=getchar();
    	for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
    	for(;isdigit(c);c=getchar()) x=x*10+c-48;
    	return f?x:-x;
    }
    
    int tcas;
    int n,m;
    LL lh[M][M];
    LL fac[M];
    
    void init(){
    	int i,j;
    	lh[0][0]=1;
    	for(i=1;i<=20;i++)
    	for(j=1;j<=i;j++)
    		lh[i][j]=(i-1)*lh[i-1][j]+lh[i-1][j-1];
    	for(fac[0]=1,i=1;i<=20;i++) fac[i]=fac[i-1]*i;
    }
    
    int main(){
    	
    	init();
    	
    	int i;	
    	tcas=rd();
    	while(tcas--){
    		n=rd(),m=rd();
    		LL ans=0;
    		for(i=1;i<=m;i++)
    			ans+=lh[n][i]-lh[n-1][i-1];
    		printf("%.4lf
    ",(db)ans/fac[n]);
    	}
    	return 0;
    }
    
  • 相关阅读:
    基于注解的IOC配置
    字符串典型问题分析
    指针与数组
    数组的本质
    数组与指针分析
    指针的本质
    #与##操作符使用
    #pragma使用分析
    #error和#line使用分析
    条件编译使用
  • 原文地址:https://www.cnblogs.com/acha/p/6442448.html
Copyright © 2011-2022 走看看