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\n",(ll)s[n-1][x+y-2]*c[x+y-2][x-1]%mod);
    }
  return 0;
}

 

转载于:https://www.cnblogs.com/Narh/p/10126519.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值