• 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 }
  • 相关阅读:
    1509 -- Glass Beads POJ
    1043: [HAOI2008]下落的圆盘
    面向对象的特性一:封装性
    java的值传递机制
    可变参数的形参方法
    方法的重载
    类及对象
    面向对象
    数组的常用算法问题
    数组的常见异常
  • 原文地址:https://www.cnblogs.com/swm8023/p/2717850.html
Copyright © 2020-2023  润新知