zoukankan      html  css  js  c++  java
  • 【HDU4372】Count the Buildings (第一类斯特林数)

    Description

    $N$座高楼,高度均不同且为$1~N$中的数,从前向后看能看到$F$个,从后向前看能看到$B$个,问有多少种可能的排列数。

    $T$组询问,答案模$1000000007$。其中$nleq 2000,Tleq 100000$

    题解:

    可以考虑现将最高的拿出来,那么可以考虑左边需要有$F-1$个房子成递增关系,那么可以将左边的房子分成$F-1$个组,右边有$B-1$个房子成递减关系,也是如此。

    不禁想到第一类斯特林数,$s(p,k)$是将将$p$个物体排成$k$个非空循环排列的方法数($k$个排列是有先后顺序的)。

    可以想到,每一组都是有顺序的(与环等价,每组把最高的转到第一个,每组再按第一个排序,右边同理,普通排序不能保证只有F个递增,B个递减)。

    除此之外,还要计算组合数,就是在$(F-1+B-1)$组中取出$F-1$个到左边,乘上即是答案。

    CODE:

     1 #include<iostream>
     2 #include<cstdio>
     3 using namespace std;
     4 
     5 #define mod 1000000007
     6 int T,N,F,B;
     7 long long c[2005][2005];
     8 long long s[2005][2005];
     9 
    10 void init(){
    11     c[0][0]=s[0][0]=1;
    12     for(int i=1;i<=2000;i++){
    13         s[i][0]=0;
    14         c[i][0]=1;
    15         for(int j=1;j<=i;j++){
    16             s[i][j]=((i-1)*s[i-1][j]+s[i-1][j-1])%mod;
    17             c[i][j]=(      c[i-1][j]+c[i-1][j-1])%mod;
    18         }
    19     }
    20 }
    21 
    22 int main(){
    23     init();
    24     scanf("%d",&T);
    25     while(T--){
    26         scanf("%d%d%d",&N,&F,&B);
    27         printf("%d
    ",s[N-1][F+B-2]*c[F+B-2][F-1]%mod);
    28     }
    29 }
  • 相关阅读:
    [leetcode-91-Decode Ways]
    [leetcode-72-Edit Distance]
    [leetcode-67-Add Binary]
    [leetcode-137-Single Number II]
    [leetcode-60-Permutation Sequence]
    [leetcode-55-Jump Game]
    [leetcode-18-4Sum]
    [leetcode-15-3Sum]
    [leetcode-47-Permutations II]
    easyui tabs update 强制刷新页面
  • 原文地址:https://www.cnblogs.com/ezoiLZH/p/9425402.html
Copyright © 2011-2022 走看看