zoukankan      html  css  js  c++  java
  • hdu 3265 第一类斯特林数

    先和第二类做一个对比

    第一类Stirling数是有正负的,其绝对值是包含n个元素的集合分作k个环排列的方法数目。
    递推公式为, S(n,0) = 0, S(1,1) = 1.   S(n+1,k) = S(n,k-1) + nS(n,k)。 
    边界条件: S(0 , 0) = 1 S(p , 0) = 0 p>=1 S(p , p) =1 p>=0 
    一些性质: S(p ,1) = 1 p>=1 S(p, 2) = 2^(p-1)– 1 p>=2   


    第二类Stirling数是把包含n个元素的集合划分为正好k个非空子集的方法的数目。   
    递推公式为:   S(n,k)=0; (n<k||k=0)   S(n,n) = S(n,1) = 1,   
    S(n,k) = S(n-1,k-1) + kS(n-1,k).
    考虑第p个物品,p可以单独构成一个非空集合,此时前p-1个物品构成k-1个非空的
    不可辨别的集合,方法数为S(p-1,k-1);
    也可以前p-1种物品构成k个非空的不可辨别的集合,
    第p个物品放入任意一个中,这样有k*S(p-1,k)种方法。

    然后说下这道题目,题目说每个房间都锁死了,切钥匙都在房间里面。我们可以任意的强行开一个门(除了1号门),然后拿到钥匙去开其他门,重复这个操作,如果开不了门,我们在强行开一个,依次类推。题目要求最多只允许强开k扇门的时候,有多大的几率把所有的门都打开。模拟一下发现和第一类斯特林数差不多,就是要特殊处理一下第一个门不能强开的情况。

    ac代码:

    #include <iostream>  
    #include <stdio.h>  
    #include <string>  
    #include <string.h>  
    #include <algorithm>  
    using namespace std;  
    typedef long long ll;  
    ll stir[22][22];  
    ll jie[22];  
      
    void init()  
    {  
      stir[1][0]=0;  
      stir[1][1]=1;  
      for(int i=2;i<=20;i++)  
         for(int j=1;j<=i;j++)  
            stir[i][j]=stir[i-1][j-1]+(i-1)*stir[i-1][j];  
      jie[1]=1;  
      for(int i=2;i<=20;i++)jie[i]=jie[i-1]*i;  
    }  
      
    int main()  
    {  
       int T;  
       scanf("%d",&T);  
       init();  
       while(T--)  
       {  
          int n,k;  
          scanf("%d%d",&n,&k);  
          ll ans=0;  
          for(int i=1;i<=k;i++)  
                ans+=stir[n][i]-stir[n-1][i-1];  
          printf("%.4lf
    ",ans*1.0/jie[n]);  
       }  
       return 0;  
    }  
  • 相关阅读:
    Python服务Debian打包新思路
    小议Python3的原生协程机制
    推送公司今日菜单内容到手机
    Python包管理工具小结
    PAT 1068. 万绿丛中一点红
    PAT 1067. 试密码
    PAT 1066. 图像过滤
    PAT 1065. 单身狗
    PAT 1064. 朋友数
    PAT 1063. 计算谱半径
  • 原文地址:https://www.cnblogs.com/z1141000271/p/7650886.html
Copyright © 2011-2022 走看看