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个叶子节点,求不同的树的 ...
随机推荐
- 隐式转换导致的cpu负载近100%
1.背景:从昨天晚上通过钉钉和邮箱一直接收到频繁报cpu负载超过90%,刚好BI同事晚上.凌晨在线上配合审计频繁DML数据库(备注:BI有一个同事有个库的DML权限,后面等审计完会收回)加上我线上线下 ...
- GitHub 官方大动作频频「GitHub 热点速览 v.22.24」
作者:HelloGitHub-小鱼干 本周 GitHub 官方 Blog 很是热闹,GitHub 官方大动作频频也带来了 GitHub Blog 的频繁更新,除了本周 News 快读收录的 GitHu ...
- Spring Data JPA系列3:JPA项目中核心场景与进阶用法介绍
大家好,又见面了. 到这里呢,已经是本SpringData JPA系列文档的第三篇了,先来回顾下前面两篇: 在第1篇<Spring Data JPA系列1:JDBC.ORM.JPA.Spring ...
- UiPath数据抓取Data Scraping的介绍和使用
一.数据抓取(Data Scraping)的介绍 使用截据抓取使您可以将浏览器,应用程序或文档中的结构化数据提取到数据库,.csv文件甚至Excel电子表格中. 二.Data Scraping在UiP ...
- word processing in nlp with tensorflow
Preprocessing Tokenizer source code:https://github.com/keras-team/keras-preprocessing/blob/master/ke ...
- PotPlayer播放百度云盘视频
需要的工具 PotPlayer.油猴tampermonkey.坚果(这个不用下载,有个账号就行) 下载地址:百度网盘 步骤 安装油猴tampermonkey 拖拽Tampermonkey_4.14.c ...
- Python简单实现自动评论、自动点赞、自动关注脚本
一些哔哔: 今天的这个脚本,是一个别人发的外包,交互界面的代码就不在这里说了,但是可以分享下自动评论.自动点赞.自动关注.采集评论和视频的数据是如何实现的 开发环境 python 3.8 运行代码py ...
- Codeforces Round #802 (Div. 2)
题集链接 A Optimal Path 水 代码 #include <bits/stdc++.h> #define endl "\n" using namespace ...
- 微信小程序接口请求/form-data/单文件、多文件上传
1.普通的微信请求封装 1 const http = (options) =>{ 2 return new Promise((resolve,reject) => { 3 wx.reque ...
- 如何给selenium.chrome写扩展拦截或转发请求
Selenium.WebDriver Selenium WebDriver 是一组开源 API,用于自动测试 Web 应用程序,利用它可以通过代码来控制chrome浏览器! 有时候我们需要mock接口 ...