HDU4372 Count the Buildings (+题解:斯特林数)
题面
(笔者翻译)
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 (+题解:斯特林数)的更多相关文章
- 【HDU 4372】 Count the Buildings (第一类斯特林数)
Count the Buildings Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
- HDU 4372 Count the Buildings——第一类斯特林数
题目大意:n幢楼,从左边能看见f幢楼,右边能看见b幢楼 楼高是1~n的排列. 问楼的可能情况 把握看到楼的本质! 最高的一定能看见! 计数问题要向组合数学或者dp靠拢.但是这个题询问又很多,难以dp ...
- HDU 4372 Count the Buildings [第一类斯特林数]
有n(<=2000)栋楼排成一排,高度恰好是1至n且两两不同.现在从左侧看能看到f栋,从右边看能看到b栋,问有多少种可能方案. T组数据, (T<=100000) 自己只想出了用DP搞 发 ...
- hdu 4372 Count the Buildings 轮换斯特林数
题目大意 n栋楼有n个不同的高度 现在限制从前面看有F个点,后面看有B个点 分析 最高那栋楼哪都可以看到 剩下的可以最高那栋楼前面分出F-1个组 后面分出B-1个组 每个组的权值定义为组内最高楼的高度 ...
- HDU4372 Count the Buildings —— 组合数 + 第一类斯特林数
题目链接:https://vjudge.net/problem/HDU-4372 Count the Buildings Time Limit: 2000/1000 MS (Java/Others) ...
- [Hdu4372] Count the Buildings
[Hdu4372] Count the Buildings Description There are N buildings standing in a straight line in the C ...
- 【HDU4372】Count the Buildings (第一类斯特林数)
Description $N$座高楼,高度均不同且为$1~N$中的数,从前向后看能看到$F$个,从后向前看能看到$B$个,问有多少种可能的排列数. $T$组询问,答案模$1000000007$.其中$ ...
- hdu 4372 Count the Buildings —— 思路+第一类斯特林数
题目:http://acm.hdu.edu.cn/showproblem.php?pid=4372 首先,最高的会被看见: 然后考虑剩下 \( x+y-2 \) 个被看见的,每个带了一群被它挡住的楼, ...
- 【题解】CJOI2019 登峰造鸡境 (Prufer序列+斯特林数)
[题解]CJOI2019 登峰造鸡境 (Prufer序列+斯特林数) 题目背景 舒服了. 题目描述 你有一颗n个点的无根树,每个点有有一个标号(1~n). 现在你知道,总共有m个叶子节点,求不同的树的 ...
随机推荐
- Centos使用crontab自动定时备份mysql的脚本
在我们网站上线之后免不了需要备份数据库,为什么要备份呢?我给大家列出了3个理由. 1.防止数据丢失 2.防止数据改错了,可以用来恢复 3.方便给客户数据 以 上几点告诉我们要经常备份,当然我今天给大家 ...
- 【Redis】Redis Cluster-集群故障转移
集群故障转移 节点下线 在集群定时任务clusterCron中,会遍历集群中的节点,对每个节点进行检查,判断节点是否下线.与节点下线相关的状态有两个,分别为CLUSTER_NODE_PFAIL和CLU ...
- 2 万字 + 30 张图 | 细聊 MySQL undo log、redo log、binlog 有什么用?
作者:小林coding 计算机八股文网站:https://xiaolincoding.com/ 大家好,我是小林. 从这篇「执行一条 SQL 查询语句,期间发生了什么?」中,我们知道了一条查询语句经历 ...
- Mac安装Brew包管理系统
Mac安装Brew包管理系统 前言 为什么需要安装brew 作为一个开发人员, 习惯了使用centos的yum和ubuntu的apt, 在mac中有没有这两个工具的平替? 有, 就是Brew. Bre ...
- Sublime Text 3 如何清除上次打开文件记录
打开顶部菜单栏:进入 Preferences => Settings-User修改如下: {"hot_exit": false,"remember_open_fil ...
- 从一道算法题实现一个文本diff小工具
众所周知,很多社区都是有内容审核机制的,除了第一次发布,后续的修改也需要审核,最粗暴的方式当然是从头再看一遍,但是编辑肯定想弄死你,显然这样效率比较低,比如就改了一个错别字,再看几遍可能也看不出来,所 ...
- BetterScroll源码阅读顺便学习TypeScript
开头 TypeScript已经出来很多年了,现在用的人也越来越多,毋庸置疑,它会越来越流行,但是我还没有用过,因为首先是项目上不用,其次是我对强类型并不敏感,所以纯粹的光看文档看不了几分钟就心不在焉, ...
- 【Java面试】RDB 和 AOF 的实现原理、优缺点
Hi,大家好,我是Mic. 一个工作了5年的粉丝私信我,最近面试碰到很多Redis相关的问题. 其中一个面试官问他Redis里面的持久化机制,没有回答得很好. 希望我帮他系统回答一下. 关于Redis ...
- npm uninstall和rm直接删除的区别
结论: 1. npm uninstall会备份包本身依赖的node_modules,rm -f会删除整个目录 2. npm uninstall不会删除被依赖的包.即使显式要删除这个包,但它被依赖不会删 ...
- 【C++】学生管理系统
[C++]学生管理系统 一道非常经典的C语言题目,用C++实现 题目如下: 输入功能:由键盘输入10个学生的学号.姓名.三科成绩,并计算出平均成绩和总成绩,然后将它存入文件stud.dat. 插入 ...