这里用到了第一类stirling数:s(n,k)=s(n-1,k-1)+(n-1)*s(n-1,k)(将n个元素进行k个环排列——k个元素的环排列等于k-1个元素的全排列),这里要将n-1(最高的那栋楼除外)栋楼分成f-1和b-1个小组,并在各小组内部进行环排列(因为每组的最高的那个位置一定在最左边,是确定的,其实就是对每组的剩下的进行全排列)。
接着用到了组合数:c(n,k)=c(n-1,k-1)+c(n-1,k)(选出n个元素中的k个的方法数),这里要将f-1+b-1组楼房中的f-1组放在最高那栋楼的左边。。。。。。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define mod 1000000007
long long way;
long long s[2005][2005],c[2005][2005];
int main()
{
int t,n,f,b,i,j,k,d;
memset(s,0,sizeof(s));
memset(c,0,sizeof(c));
s[1][1]=1; c[1][1]=1;
for(i=0;i<=2000;i++) c[i][0]=1;
for(i=2;i<2001;i++) //这部分要放在while循环外,否则会超时
for(j=1;j<=i;j++){
s[i][j]=(s[i-1][j-1]+(i-1)*s[i-1][j])%mod;
c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
}
scanf("%d",&t);
while(t--){
scanf("%d %d %d",&n,&f,&b);
if(f+b-2<2001) //这个条件必须有,因为前面数组范围有限
way=(s[n-1][f+b-2]*c[f+b-2][f-1])%mod;
else
way=0;
printf("%I64d\n",way);
}
// system("pause");
return 0;
}