题目链接:
https://vjudge.net/problem/HDU-4372
题目:
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
题解:
题意:有N个房子在一条直线上,所有房子的高度在1到N之间,并且所有房子的高度都不相同,从左往右看能看到F个房子,从右往左看能看到B个房子,问房子的排列有多少种方案。
从左往右看能看到F个房子,不算最高为N的那个房子,能看到F-1个房子;
从右往左看能看到B个房子,不算最高为N的那个房子,能看到B-1个房子;
那么就能看成是把1到N-1 总共N-1个元素分配到 F-1+B-1个圆排列里,第一类Stirling解决的问题就是 :把n个不同的元素分配到k个圆排列里,圆不能为空的方案数。 求出圆排列的方案数,再乘上C(F+B-2,F-1)就是最后的答案,C(F+B-2,F-1)的意思是从F+B-2个圆排列选F-1放到 高度为N的房子的左边的方案数。能看到的房子就是每个圆排列中最高的那个房子。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2005;
const int mod=1e9+7;
ll c[maxn][maxn],f[maxn][maxn];
void init(){
c[0][0]=f[0][0]=1;
for(int i=1;i<=2000;i++){
c[i][0]=c[i][i]=1;
f[i][0]=0;f[i][i]=1;
}
for(int i=2;i<=2000;i++){
for(int j=1;j<i;j++){
c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;
f[i][j]=(f[i-1][j-1]+(i-1)*f[i-1][j])%mod;
}
}
}
int main(){
init();
int t,n,a,b;
cin>>t;
while(t--){
scanf("%d%d%d",&n,&a,&b);
if(a+b-2>n) printf("0\n");
else printf("%lld\n",c[a+b-2][a-1]*f[n-1][a+b-2]%mod);
}
return 0;
}