zoukankan      html  css  js  c++  java
  • hdu 4372 Count the Buildings——第一类斯特林数

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=4372

    刨去最高的,剩下的就是 x+y-1 个块。一个块如果已知取哪些数,则最左(右)边是哪个数已经确定,剩下的位置随便排列;其实就是一个圆排列,每个排列从最大元素旁边断成链。

    所以就是 n-1 个数分成 x+y-2 个圆排列,即第一类斯特林数。再乘上 x+y-2 个里选 x-1 个放在最高点左边的方案数即可。

    注意 x+y-1 可能大于 n 。本来斯特林数的那个位置是0,可以不用特判,但可能爆数组!所以开大数组或者特判。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N=4005,mod=1e9+7;
    int T,n,s[N][N],c[N][N];
    int rdn()
    {
      int ret=0;bool fx=1;char ch=getchar();
      while(ch>'9'||ch<'0'){if(ch=='-')fx=0;ch=getchar();}
      while(ch>='0'&&ch<='9')ret=ret*10+ch-'0',ch=getchar();
      return fx?ret:-ret;
    }
    void upd(int &x){x>=mod?x-=mod:0;}
    void init()
    {
      int lm=2000;
      s[0][0]=1;
      for(int i=1;i<=lm;i++)
        for(int j=1;j<=i;j++)
          s[i][j]=(s[i-1][j-1]+(ll)s[i-1][j]*(i-1))%mod;
      for(int i=0;i<=lm;i++)c[i][0]=1;
      for(int i=1;i<=lm;i++)
        for(int j=1;j<=i;j++)
          c[i][j]=c[i-1][j-1]+c[i-1][j],upd(c[i][j]);
    }
    int main()
    {
      init();T=rdn();
      while(T--)
        {
          n=rdn();int x=rdn(),y=rdn();
          /*
          if(x+y-1>n)puts("0");
          else */printf("%lld
    ",(ll)s[n-1][x+y-2]*c[x+y-2][x-1]%mod);
        }
      return 0;
    }
  • 相关阅读:
    软件工程(2018)第一次作业
    SQA计划
    再冲刺
    第三次冲刺
    第二次冲刺
    小组第一次冲刺
    团队合作初体验
    关于git的认识与想法
    我的第一篇博客
    SQA计划和系统测试规程
  • 原文地址:https://www.cnblogs.com/Narh/p/10126519.html
Copyright © 2011-2022 走看看