zoukankan      html  css  js  c++  java
  • [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组的方案就是:$$
    egin{bmatrix}
    n-1 A+B-2
    end{bmatrix}$$
    这A-1+B-1组还有放左边和右边的方案,也就是:$$inom{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
    ",f[N-1][A+B-2]*C(A+B-2,A-1)%Mod);
        }
        return 0;
    }
    
    
  • 相关阅读:
    java里如何使用输入流和输出流实现读取本地文件里内容和写出到本地文件里
    Windows 命令行基础(博主推荐)
    Python2.7编程基础(博主推荐)
    27 个Jupyter Notebook的小提示与技巧
    java里如何实现循环打印出字符或字符数组里的内容
    [转]angularjs之ui-grid 使用详解
    [转]AngularJS 实现 Table的一些操作(示例大于实际)
    [转]js 回车转成TAB(利用tabindex)
    [转] Entity Framework添加记录时获取自增ID值
    [转]使用依赖关系注入在 ASP.NET Core 中编写干净代码
  • 原文地址:https://www.cnblogs.com/wxjor/p/9558259.html
Copyright © 2011-2022 走看看