[Hdu4372] Count the Buildings

[Hdu4372] Count the Buildings

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

The 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为分界,把n拿出来单独考虑。
所以A变成A-1,B变成B-1。
然后考虑把这个序列看成一段一段的,用最长连续上升&最长连续倒序上升序列中的元素看成分界,那么段中剩下的元素可以随便换,设段长为\(x\),那么其中便能换\((x-1)!\)种方案。
\((x-1)!\),这不是把\((x-1)\)个元素分成一个轮换的方案数么?每次我们只需要把这个轮换中的最大的拿出来当做头部就可以了。
于是分成A-1+B-1组的方案就是:$$
\begin{bmatrix}
n-1 \ A+B-2
\end{bmatrix}$$
这A-1+B-1组还有放左边和右边的方案,也就是:$$\binom{A+B-2}{A-1}$$
由于左边和右边分组确定后顺序是按照组内最大值排序的,所以顺序是唯一的,无需考虑。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<algorithm>
 
using namespace std;
#define LL long long
 
inline LL read(){
    LL x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
const LL INF = 2147483600;
const LL MAXN = 4010;
const LL Mod = 1000000007;
 
LL N,A,B,T; LL fac[MAXN+1],ifac[MAXN+1],inv[MAXN+1];
LL f[MAXN+1][MAXN+1];
 
inline void init(){
    fac[0]=1; ifac[1]=1; inv[1]=1; ifac[0]=1;
    for(LL i=1;i<=MAXN;i++) fac[i]=fac[i-1]*i%Mod;
    for(LL i=2;i<=MAXN;i++)
        inv[i]=(Mod-(Mod/i))*inv[Mod%i]%Mod,ifac[i]=ifac[i-1]*inv[i]%Mod;
    f[0][0]=1; for(LL i=1;i<=MAXN;i++){
        for(LL j=1;j<=MAXN;j++)
            f[i][j]=((i-1)*f[i-1][j]%Mod+f[i-1][j-1])%Mod;
    } return ;
}
inline LL C(LL n,LL m){
    if(n<m) return 0; if(!m) return 1;
    return fac[n]*ifac[n-m]%Mod*ifac[m]%Mod;
}
 
int main(){
    //freopen(".in","r",stdin);
    //freopen(".out","w",stdout);
    T=read(); init();
    while(T--){
        N=read(),A=read(),B=read(); //cout<<f[N-1][A+B-2]<<endl;
        printf("%lld\n",f[N-1][A+B-2]*C(A+B-2,A-1)%Mod);
    }
    return 0;
}

posted @ 2018-08-30 09:34  wxjor  阅读(166)  评论(0编辑  收藏  举报