题面

(笔者翻译)

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.

有n座高楼,从左往右数第 i 座楼的高度为 ai,每座高楼高度互不相同,且 1 ≤ ai ≤ n ,换言之,n座高楼高度形成的序列为1~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.

如果有平行光从最左端往右照,那么光能照到的高楼数为 F,如果有平行光从最右端往左照,那么光能照到的高楼数为 B,

(上图为F = 3,B = 2的一个例子)

Now, given N, F, B, your task is to figure out how many ways all the buildings can be.

告诉你n,F和B,让你求符合n、F 、B条件的合法序列有多少个

Input

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).

有最多1e5个数据,n、F、B都是小于等于2000的正整数,最终答案要取模 1e9+7。

题解

既然每个高度不相同,那么对F和B有重复贡献的有且仅有最高的那座楼,

最高的楼左边有F-1个递增排列的楼,每座楼到右边那座比它高的楼中间都有一堆小弟(比它小),

最高的楼右边有B-1个递减排列的楼,每座楼到左边那座比它高的楼中间也有一堆小弟(比它小),

那么说,除了最高的楼之外,其他的楼共有F+B-2个团体,每个团体有一座最高的楼(要算贡献的楼)和一堆小弟(可以没有),

从中选F-1个团体到最大楼的左边(组合数C(F+B-2 , F-1)),他们之间的顺序就确定了(递增),然后小弟们就在对应老大右边乱排列,

剩下的B-1个团体到最大楼的右边(加起来正好 F+B-2 个),他们之间的顺序也确定了(递减),然后小弟们就在对应老大左边乱排列,

想好了放团体的方案数后,我们来想安排团体内部的方案

对于每个团体,把最大的一个拉入队首,剩下的随便排,

这不就是圆排列吗?相关于把每个圈最大的一个转到第一个。

所以,分团体以及安排团体内部的顺序的方案数就是 s(n-1,F+B-2) (第一类斯特林数

把s(n-1,F+B-2)和C(F+B-2 , F-1)乘起来完事,

注意T很大,因此要n^2预处理s和C,然后判断无解的情况。

CODE

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<algorithm>
#define MAXN 2005
#define MAXM 35
#define ENDL putchar('\n')
#define LL long long
#define DB double
#define lowbit(x) ((-x)&(x))
//#define int LL
using namespace std;
inline LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s == '-')f = -1;s = getchar();}
while(s >= '0' && s <= '9') {x = x * 10 + (s - '0');s = getchar();}
return x * f;
}
const int jzm = 1000000007;
int n,m,i,j,o,k;
int s[MAXN][MAXN],C[MAXN][MAXN];
int main() {
s[0][0] = 1;
C[0][0] = 1;
for(int i = 1;i <= 2000;i ++) {
C[i][0] = 1;
for(int j = 1;j <= i;j ++) {
s[i][j] = (s[i-1][j-1] +0ll+ (i-1ll) *1ll* s[i-1][j] % jzm) % jzm;
C[i][j] = (C[i-1][j-1] +0ll+ C[i-1][j]) % jzm;
}
}
int T = read();
while(T --) {
n = read();
int F = read(),B = read();
if(F+B-1 > n || max(F,B) <= 1) {
printf("0\n");
continue;
}
int ans = s[n-1][F+B-2] *1ll* C[F+B-2][F-1] % jzm;
printf("%d\n",ans);
}
return 0;
}

第一类斯特林数

简单解释一下

想增进了解的点这里

HDU4372 Count the Buildings (+题解:斯特林数)的更多相关文章

  1. 【HDU 4372】 Count the Buildings (第一类斯特林数)

    Count the Buildings Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Othe ...

  2. HDU 4372 Count the Buildings——第一类斯特林数

    题目大意:n幢楼,从左边能看见f幢楼,右边能看见b幢楼 楼高是1~n的排列. 问楼的可能情况 把握看到楼的本质! 最高的一定能看见! 计数问题要向组合数学或者dp靠拢.但是这个题询问又很多,难以dp ...

  3. HDU 4372 Count the Buildings [第一类斯特林数]

    有n(<=2000)栋楼排成一排,高度恰好是1至n且两两不同.现在从左侧看能看到f栋,从右边看能看到b栋,问有多少种可能方案. T组数据, (T<=100000) 自己只想出了用DP搞 发 ...

  4. hdu 4372 Count the Buildings 轮换斯特林数

    题目大意 n栋楼有n个不同的高度 现在限制从前面看有F个点,后面看有B个点 分析 最高那栋楼哪都可以看到 剩下的可以最高那栋楼前面分出F-1个组 后面分出B-1个组 每个组的权值定义为组内最高楼的高度 ...

  5. HDU4372 Count the Buildings —— 组合数 + 第一类斯特林数

    题目链接:https://vjudge.net/problem/HDU-4372 Count the Buildings Time Limit: 2000/1000 MS (Java/Others)  ...

  6. [Hdu4372] Count the Buildings

    [Hdu4372] Count the Buildings Description There are N buildings standing in a straight line in the C ...

  7. 【HDU4372】Count the Buildings (第一类斯特林数)

    Description $N$座高楼,高度均不同且为$1~N$中的数,从前向后看能看到$F$个,从后向前看能看到$B$个,问有多少种可能的排列数. $T$组询问,答案模$1000000007$.其中$ ...

  8. hdu 4372 Count the Buildings —— 思路+第一类斯特林数

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=4372 首先,最高的会被看见: 然后考虑剩下 \( x+y-2 \) 个被看见的,每个带了一群被它挡住的楼, ...

  9. 【题解】CJOI2019 登峰造鸡境 (Prufer序列+斯特林数)

    [题解]CJOI2019 登峰造鸡境 (Prufer序列+斯特林数) 题目背景 舒服了. 题目描述 你有一颗n个点的无根树,每个点有有一个标号(1~n). 现在你知道,总共有m个叶子节点,求不同的树的 ...

随机推荐

  1. PyTorch DataLoader NumberWorkers Deep Learning Speed Limit Increase

    这意味着训练过程将按顺序在主流程中工作. 即:run.num_workers.   ,此外, ,因此,主进程不需要从磁盘读取数据:相反,这些数据已经在内存中准备好了. 这个例子中,我们看到了20%的加 ...

  2. 【Redis】Redis Cluster初始化及PING消息的发送

    Cluster消息类型定义 #define CLUSTERMSG_TYPE_PING 0 /* Ping消息类型,节点间进行通信交换信息的消息 */ #define CLUSTERMSG_TYPE_P ...

  3. 使用Node.js还可以发邮件

    前言 今天,我们给大家开发一个小效果.篇幅比较短,主要给大家展示效果.实战 首先我们初始化一个Node项目 npm init -y 创建一个app.js文件 'use strict'; const n ...

  4. 「BUAA OO Unit 4 HW16」第四单元总结与课程回顾

    「BUAA OO Unit 4 HW16」第四单元总结与课程回顾 目录 「BUAA OO Unit 4 HW16」第四单元总结与课程回顾 Part 0 第四单元作业架构设计 架构设计概要 AppRun ...

  5. Spring Boot:整合Swagger

    1.先创建一个SpringBoot项目 其中application.properties文件中是创建项目时自动添加的配置. 2.添加相关maven依赖 <!--swagger--> < ...

  6. XXXX系统测试计划

    XXXX系统测试计划 目录 XXXX系统测试计划 目标 概述 项目背景 适用范围 组织形式 组织架构图 角色及职责 测试工作分工 团队协作 测试对象 应测试特性 不被测试特性 测试任务安排 系统测试任 ...

  7. who is the next one?

    Turn-Taking:  参加会话的人参加整个会话的过程中轮流说话,end-of-utterance detection systems,是对说话转变的预测,既什么时候发生对话者之间的转变. Eva ...

  8. Redis 内存优化神技,小内存保存大数据

    大家好,我是「码哥」,大家可以叫我靓仔. 这次码哥跟大家分享一些优化神技,当你面试或者工作中你遇到如下问题,那就使出今天学到的绝招,一招定乾坤! 如何用更少的内存保存更多的数据? 我们应该从 Redi ...

  9. SQL Server 中的 ACID 属性

    SQL Server 中的事务是什么? SQL Server 中的事务是一组被视为一个单元的 SQL 语句,它们按照"做所有事或不做任何事"的原则执行,成功的事务必须通过 ACID ...

  10. Data too long for column 'xxx' at row

    Data too long for column 'xxx' at row 数据库的默认的utff-8,且连接的字符串也设置了utf-8,数据库字段用的text,但是还是报错,原因超出了长度,要最大的 ...