HDU3265 Examining the Rooms【stirling数】

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3625

题目大意:

有N个房间,每个房间的要是随机放在某个房间内,概率相同。有K次炸门的机会。

求能打开所有房间门,进入所有房间的概率有多大。

解题思路:

门和钥匙的对应关系出现环。打开一个门后,环内的门都可以打开。也就意味着:

N个房间的钥匙与门形成1~K个环的概率有多大。

也就是求N个元素,构成K个以内的环,且1不成自环的概率。

N个元素形成K个环的方法数是第一类stirling数 S(N,K)。

N个元素形成K个环,且1成自环的方法数是S(N-1,K-1)。

则N个元素形成K个环,且1不成自环的方法数是S(N,K) - S(N-1,K-1)。

要是随机放的总的方法数为N!。

则概率P(N,K)为( S(N,K) - S(N-1,K-1) + S(N,K-1) - S(N-1,K-2) + … +

S(N,1) - S(N,0) ) / N!

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define LL long long
using namespace std;

LL F[25],Stirling[25][25];

void Solve()
{
    F[0] = 1;
    for(int i = 1; i <= 20; ++i)    //阶乘数组
        F[i] = i*F[i-1];

    for(int i = 1; i <= 20; ++i)    //算出第一类stirling数
        Stirling[i][0] = 0;
    Stirling[1][1] = 1;
    for(int i = 1; i <= 20; ++i)
    {
        for(int j = 1; j <= i; ++j)
        {
            if(i == j)
                Stirling[i][j] = 1;
            else
                Stirling[i][j] = Stirling[i-1][j-1] + (i-1)*Stirling[i-1][j];
        }
    }

    for(int i = 1; i <= 20; ++i)    //取绝对值
    {
        for(int j = 1; j <= 20; ++j)
        {
            Stirling[i][j] = abs(Stirling[i][j]);
        }
    }
}

int main()
{
    Solve();
    int T,N,K;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d %d",&N,&K);
        LL sum = 0;
        for(int i = 1; i <= K; ++i)
            sum += Stirling[N][i] - Stirling[N-1][i-1];
        printf("%.4f\n",(double)sum / (double)F[N]);    //.4lf输出不了正确结果
    }

    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-06 17:19:45

HDU3265 Examining the Rooms【stirling数】的相关文章

HDU 3625 Examining the Rooms:第一类stirling数

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3625 题意: 有n个房间,每个房间里放着一把钥匙,对应能开1到n号房间的门. 除了1号门,你可以踹开任意一扇门(不用钥匙),但你最多只能踹k次. 问你能将所有门打开的概率. 题解: · P(打开所有门) = 能打开所有门的钥匙放置情况数 / 钥匙放置的总情况数 · 钥匙放置的总情况数 = n! 那么考虑下能打开所有门的钥匙放置情况数... 由于每个房间里有且只有一把钥匙,所以如果将每个房间连向房间内

Examining the Rooms HDU - 3625(第一类斯特林数)

Examining the Rooms HDU - 3625 题意:n个房间,每个房间里有一把钥匙(等概率),每进到一个房间可以得到钥匙去该钥匙对应的房间,如果当前没有钥匙则可以破门而入(1号房间不能破门而入),不过最多破门而入k次,问成功进入n个房间的总概率. 明显是求n个元素的i个环排列,i = 1,2,--,k. 不过要减去第一个房间自环的情况. 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long lon

组合计数 &amp;&amp; Stirling数

参考: http://blog.csdn.net/qwb492859377/article/details/50654627 http://blog.csdn.net/acdreamers/article/details/8521134 http://blog.csdn.net/sr_19930829/article/details/40888349 球,盒子都可以分成是否不能区分,和能区分,还能分成是否能有空箱子,所以一共是8种情况,我们现在来一一讨论. 1.球同,盒不同,无空箱 C(n-1,

HDU4372-Count the Buildings(第一类Stirling数+组合计数)

Count the Buildings Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 528    Accepted Submission(s): 171 Problem Description There are N buildings standing in a straight line in the City, numbere

HDU 4372 Count the Buildings:第一类Stirling数

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4372 题意: 有n栋高楼横着排成一排,各自的高度为1到n的一个排列. 从左边看可以看到f栋楼,从右边看可以看到b栋楼,并且高的楼会挡住低的楼. 问你这些楼有多少种排列方法. 题解: 由于高的楼会挡住低的楼,所以这些楼首先会被划分成f+b-2个区域(除去中间最高的楼),并且左边有f-1个,右边有b-1个. 对于一个区域(假设在左边),这个区域由若干栋楼组成,并且最高的楼一定在最左边. 那么,由一个区域

Bell(hdu4767+矩阵+中国剩余定理+bell数+Stirling数+欧几里德)

Bell Time Limit:3000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 4767 Description What? MMM is learning Combinatorics!? Looks like she is playing with the bell sequence now: bell[n] = number of ways to part

贝尔数(来自维基百科)&amp; Stirling数

贝尔数 贝尔数以埃里克·坦普尔·贝尔(Eric Temple Bell)为名,是组合数学中的一组整数数列,开首是(OEIS的A000110数列): Bell Number Bn是基数为n的集合的划分方法的数目.集合S的一个划分是定义为S的两两不相交的非空子集的族,它们的并是S.例如B3 = 5因为3个元素的集合{a, b, c}有5种不同的划分方法: {{a}, {b}, {c}} {{a}, {b, c}} {{b}, {a, c}} {{c}, {a, b}} {{a, b, c}}; B0

HDU 2643 Rank:第二类Stirling数

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2643 题意: 有n个个选手参赛,问排名有多少种情况(可以并列). 题解: 简化问题: 将n个不同的元素放到i个有差别的盒子中,情况数为P(n,i),求∑P(n,i) (1<=i<=n) 再简化: 将n个不同的元素放到i个无差别的盒子中,情况数为S(n,i),求∑( S(n,i)*i! ) (1<=i<=n) 哇这是第二类Stirling数 ( ̄▽ ̄)~* 递推式:s(n,k) = s(

两类Stirling数

转:http://blog.csdn.net/acdreamers/article/details/8521134 第一类Stirling数 s(p,k)    s(p,k)的一个的组合学解释是:将p个物体排成k个非空循环排列的方法数. s(p,k)的递推公式: s(p,k)=(p-1)*s(p-1,k)+s(p-1,k-1) ,1<=k<=p-1 边界条件:s(p,0)=0 ,p>=1  s(p,p)=1  ,p>=0   递推关系的说明: 考虑第p个物品,p可以单独构成一个非空