HDU4372 Count the Buildings —— 组合数 + 第一类斯特林数
题目链接:https://vjudge.net/problem/HDU-4372
Count the Buildings
Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2509    Accepted Submission(s): 815
Now, given N, F, B, your task is to figure out how many ways all the buildings can be.
Next T lines, each line consists of three integer N, F, B, (0<N, F, B<=2000) described above.
3 2 2
3 2 1
1
题意:
有n幢高度不一的楼房位于一条直线上,问有多少种方案数,使得人从第一幢往前看时看到f幢,从最后一幢往后看时看到b幢?
题解:

1.可知最高的那栋必定能够看到,于是就分成了左边和右边。
2.对于左边的楼而言,需要把他们分成f-1组,每一组的最高楼在最左边,这样就把组内其他的楼遮住了,于是就看到f-1栋。对于右边的也如此。
3.那怎么分组呢?首先,求出求出第一类斯特林数 S[n-1][f-1+b-1],即把除了最高楼之外的楼房排成f-1+b-1个圈。由于每一组中最高的楼房固定在左边或右边,这样就对应了圈。换句话说,对排列好的一个圈选定一栋楼房,而这栋楼房就是最高的那栋,然后再把这个圈展开成一列,这样就对应了一组。所以可以用第一类斯特林数求出分组的方案数。
4.分好组后,就直接从 f+b-2组中抽取f-1组放在左边(由于要求递增,所以选出来之后他们的位置就固定了,不需要再排列),总有 C[f+b-2][f-1]种选择。
5.综上,总共有 S[n-1][f-1+b-1] * C[f+b-2][f-1] 种方案数。注意, 当n-1<f+b-2时, 问题无解。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <set>
using namespace std;
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int MOD = 1e9+;
const int MAXN = 2e3+; LL S[MAXN][MAXN], C[MAXN][MAXN]; void init()
{
for(int i = ; i<MAXN; i++)
{
C[i][] = ;
for(int j = ; j<=i; j++)
C[i][j] = (C[i-][j-]+C[i-][j])%MOD;
} memset(S, , sizeof(S));
for(int i = ; i<MAXN; i++)
{
S[i][] = ; S[i][i] = ;
for(int j = ; j<i; j++)
S[i][j] = (((i-)*S[i-][j])%MOD + S[i-][j-])%MOD;
}
} int main()
{
init();
int T, n, f, b;
scanf("%d", &T);
while(T--)
{
scanf("%d%d%d", &n, &f, &b);
LL ans;
if(n-<f+b-) ans = ;
else ans = (1LL*S[n-][f+b-]*C[f+b-][f-])%MOD;
printf("%lld\n", ans);
}
}
HDU4372 Count the Buildings —— 组合数 + 第一类斯特林数的更多相关文章
- 【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 \) 个被看见的,每个带了一群被它挡住的楼, ...
 - HDU 4372 Count the Buildings:第一类Stirling数
		
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4372 题意: 有n栋高楼横着排成一排,各自的高度为1到n的一个排列. 从左边看可以看到f栋楼,从右边看 ...
 - 【HDU 4372】 Count the Buildings (第一类斯特林数)
		
Count the Buildings Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Othe ...
 - HDU4372 Count the Buildings (+题解:斯特林数)
		
题面 (笔者翻译) There are N buildings standing in a straight line in the City, numbered from 1 to N. The h ...
 - HDU 4372 Count the Buildings——第一类斯特林数
		
题目大意:n幢楼,从左边能看见f幢楼,右边能看见b幢楼 楼高是1~n的排列. 问楼的可能情况 把握看到楼的本质! 最高的一定能看见! 计数问题要向组合数学或者dp靠拢.但是这个题询问又很多,难以dp ...
 - 洛谷P4609 [FJOI2016]建筑师(第一类斯特林数+组合数)
		
题面 洛谷 题解 (图片来源于网络,侵删) 以最高的柱子\(n\)为分界线,我们将左边的一个柱子和它右边的省略号看作一个圆排列,右边的一个柱子和它左边的省略号看作一个圆排列,于是,除了中间的最高的柱子 ...
 - 【2019雅礼集训】【CF 960G】【第一类斯特林数】【NTT&多项式】permutation
		
目录 题意 输入格式 输出格式 思路 代码 题意 找有多少个长度为n的排列,使得从左往右数,有a个元素比之前的所有数字都大,从右往左数,有b个元素比之后的所有数字都大. n<=2*10^5,a, ...
 - 【CF715E】Complete the Permutations(容斥,第一类斯特林数)
		
[CF715E]Complete the Permutations(容斥,第一类斯特林数) 题面 CF 洛谷 给定两个排列\(p,q\),但是其中有些位置未知,用\(0\)表示. 现在让你补全两个排列 ...
 
随机推荐
- ELK之收集Java日志、通过TCP收集日志
			
1.Java日志收集 使用codec的multiline插件实现多行匹配,这是一个可以将多行进行合并的插件,而且可以使用what指定将匹配到的行与前面的行合并还是和后面的行合并. 语法示例: inpu ...
 - mybatis-plus generator template 中的全部属性
			
{ "date": "2018-10-30", "superServiceImplClassPackage": "com.baom ...
 - Java-HashMap原理解析
			
本文分析HashMap的实现原理. 数据结构(散列表) HashMap是一个散列表(也叫哈希表),用来存储键值对(key-value)映射.散列表是一种数组和链表的结合体,结构图如下: 简单来说散列表 ...
 - 配置laravel的nginx站点
			
server{}配置 server{ #端口配置 listen 80; #域名配置 server_name laravel.cc; index index.php index.html index.h ...
 - django_session
			
基于cookie做用户验证时:敏感信息不适合放在cookie中 session依赖cookie session原理 cookie是保存在用户浏览器端的键值对 session是保存在服务器端的键值对 s ...
 - 谈谈Runtime类中的freeMemory,totalMemory,maxMemory几个方法
			
最近在网上看到一些人讨论到java.lang.Runtime类中的freeMemory(),totalMemory(),maxMemory ()这几个方法的一些问题,很多人感到很疑惑,为什么,在jav ...
 - 嵌入式Linux驱动案例之中的一个
			
前几天解决一个嵌入式Linux驱动问题,做为一个案例进行记录. 本案例是一个CPU通过LocalBus总线訪问外围一个设备,详细设备是一个DSP器件.在实际应用中,性能要求非常高,对数据訪问速度提出比 ...
 - 【C语言】求两个数中不同的位的个数
			
//求两个数中不同的位的个数 #include <stdio.h> int count_different(int a, int b) { int count = 0; int c = a ...
 - 如何学习Java?
			
一点感悟 java作为一门编程语言,在各类编程语言中作为弄潮儿始终排在前三的位置,这充分肯定了java语言的魅力,在实际项目应用中,我们已经无法脱离javaa(Ps当然你可以选择不使用),但它的高性能 ...
 - gdb调试段错误及使用
			
在编程调试中,经常出现段错误,此时可用gdb调试.具体方法为注册段错误信号处理函数,在处理函数中启动gdb.具体代码如下: void segv_handler(int no) { ]; ]; FILE ...