# 斯特林数与放球问题

2018 年 7 月 27 日 07:02

## 第一类斯特林数

\displaystyle s(i,j)=s(i-1,j-1)+(i-1)\ast s(i-1,j)


## 第二类斯特林数

\displaystyle S(i,j)=S(i-1,j-1)+j\ast S(i-1,j)


$S(i,j)$ 的其他表示方法是 $S_i^{(j)}$ 或者 $\begin{Bmatrix} i \\ j \end{Bmatrix}$ 。

## 例题：HDU 4372：Count the Buildings

### Problem Description

There are N buildings standing in a straight line in the City, numbered from 1 to N. The heights of all the buildings are distinct and between 1 and N. You can see F buildings when you standing in front of the first building and looking forward, and B buildings when you are behind the last building and looking backward. A building can be seen if the building is higher than any building between you and it.
Now, given N, F, B, your task is to figure out how many ways all the buildings can be.

### Input

First line of the input is a single integer T (T<=100000), indicating there are T test cases followed.
Next T lines, each line consists of three integer N, F, B, (0<N, F, B<=2000) described above.

### Output

For each case, you should output the number of ways mod 1000000007(1e9+7).

### Sample Input

2
3 2 2
3 2 1


### Sample Output

2
1


### Solution

\displaystyle s(n-1,a-1+b-1)\ast C_{a-1+b-1}^{a-1}


### Code

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=2005,tt=1e9+7;
int T,n,a,b,f[maxn][maxn],c[maxn][maxn];
int ret=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9') {if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9') ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}
inline void MakeDP(){
f[1][1]=1;
for (int i=2;i<=2000;i++)
for (int j=1;j<=i;j++)
f[i][j]=((long long)f[i-1][j-1]+(long long)(i-1)*f[i-1][j]%tt)%tt;
for (int i=0;i<=2000;i++) c[i][0]=1;
for (int i=1;i<=2000;i++){
c[i][0]=c[i][i]=1;
for (int j=1;j<i;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%tt;
}
}
int main(){
MakeDP();
while (T--){
if (a+b-2>2000){printf("0\n");continue;}
printf("%lld\n",(long long)f[n-1][a-1+b-1]*c[a-1+b-1][a-1]%tt);
}
return 0;
}