zoukankan      html  css  js  c++  java
  • HDU 4372 Count the Buildings [组合数学]

      N个楼高度1~N,在最前面可以看到F栋楼,最后面可以看到B栋楼,求有多少种可能的排列。

      对某几个数组成的集合,可以定义一个最大表示法,就是最大的数在最前面。F+B栋楼,去掉N之后,就是F+B-2个集合,选中其中的B-1个在前方按集合最大值升序排列,后方反之。然后对每个集合,不管怎样排列,看到的都是最大的那一个,可以想到是第一类stirling数,用N-1个数组成F+B-2个圈的排列数。

      所以答案就是C(F+B-2,F-1)*S(N-1,F+B-2)。O(N^2)预处理,O(1)查询。

      

     1 #include <string.h>
     2 #include <stdio.h>
     3 #define MAXN 2005
     4 #define MOD 1000000007
     5 typedef long long LL;
     6 int n, f, b, cas;
     7 int c[MAXN][MAXN], s[MAXN][MAXN];
     8 void init(){
     9     for (int i = 0; i < MAXN; c[i++][0] = 1)
    10         for (int j = 1; j <= i; j++)
    11             c[i][j] = (c[i-1][j-1] + c[i-1][j]) % MOD;
    12     s[1][1] = 1;
    13     for (int i = 2; i < MAXN; i++)
    14         for (int j = 1; j <= i; j++)
    15             s[i][j] = (s[i-1][j-1] + (LL)(i-1) * s[i-1][j]) % MOD;
    16 }
    17 int main(){
    18     init();
    19     scanf("%d", &cas);
    20     while (cas--) {
    21         scanf("%d%d%d", &n, &f, &b);
    22         if(f+b-2>n-1)printf("%d\n",0);
    23         else printf("%d\n",(LL)c[f+b-2][f-1] * s[n-1][f+b-2] % MOD);
    24     }
    25     return 0;
    26 }
  • 相关阅读:
    [转载]c++转python
    [转载]One-hot编码
    [转载]各种机器学习算法的应用场景
    SVC和SVR
    机器学习-正则化+回归与分类辨析
    C#编译时,提示缺少NuGet包
    C++中 左值和右值的区别
    C++11并发编程实战 免费书籍
    静态库和动态库
    C++中string类
  • 原文地址:https://www.cnblogs.com/swm8023/p/2717850.html
Copyright © 2011-2022 走看看