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个叶子节点,求不同的树的 ...
随机推荐
- vue组件data函数
vue组件data通常定义为一个函数并return一个对象,对象中定义的就是组件数据,当然定义数据还有props.computed等方式. data如果直接定义为对象data: {message: ' ...
- hyperlpr centos 使用记录
1.下载最新版python3.7 Anacondawget https://repo.anaconda.com/archive/Anaconda3-5.3.1-Linux-x86_64.sh 2.安装 ...
- SpringCloudAlibaba学习(解决SpringBoot初始化以及Nginx启动出错问题)
微服务强调每个服务都是单独的数据库 在不使用微服务的情况下可以采用分布式架构,通过Template来调用远程的Rest接口 但这种方式维护起来很麻烦,而且有很多弊端. 一.环境搭建 1.首先搭建Spr ...
- NC50528 滑动窗口
NC50528 滑动窗口 题目 题目描述 给一个长度为N的数组,一个长为K的滑动窗体从最左端移至最右端,你只能看到窗口中的K个数,每次窗体向右移动一位,如下图: 你的任务是找出窗体在各个位置时的最大值 ...
- 爬虫(14) - Scrapy-Redis分布式爬虫(1) | 详解
1.什么是Scrapy-Redis Scrapy-Redis是scrapy框架基于redis的分布式组件,是scrapy的扩展:分布式爬虫将多台主机组合起来,共同完成一个爬取任务,快速高效地提高爬取效 ...
- PTA(BasicLevel)-1094 谷歌的招聘
一.问题定义 2004 年 7 月,谷歌在硅谷的 101 号公路边竖立了一块巨大的广告牌(如下图)用于招聘.内容超级简单,就是一个以 .com 结尾的网址, 而前面的网址是一个 10 位素数,这个素数 ...
- SDK导入问题 __imp_与__imp__
目前刚刚实习一周,接触的第一个项目是CMake编译的QT项目,需要引入公司的SDK,编译能过去但是程序就是找不到SDK的接口, 排查了半天发现问题在于:公司的SDK是32位的,自己项目的build k ...
- DNS 系列(二):DNS 记录及工作方式,你了解吗?
在上一篇<DNS 系列(一):为什么更新了 DNS 记录不生效?>中,我们主要讲解了 DNS 和 DNS 传播,知道了网络通信主要通过 IP 地址来进行,而域名系统(DNS)则是保证用户在 ...
- 001 Redis 配置
Redis缓存 1.配置Redis //Redis 配置文件 @Configuration public class RedisConfiguration { @Bean public RedisTe ...
- postgres备份与恢复
一 利用pgAdmin工具进行备份与恢复 pgAdmin是postgres官方的客户端管理工具,可以进行数据库的涉及与维护. 示例:以logs库为例记录操作 1) 右击需要备份的数据( ...