HDU4372-Count the Buildings【第一类Stirling数】+【组合数】
<题目链接>
<转载于 >>> >
题目大意:
N座高楼,高度均不同且为1~N中的数,从前向后看能看到F个,从后向前看能看到B个,问有多少种可能的排列数。
0 < N, F, B <= 2000
解题分析:
首先我们知道一个结论:n的环排列的个数与n-1个元素的排列的个数相等,因为P(n,n)/n=(n-1)!。
可以肯定,无论从最左边还是从最右边看,最高的那个楼一定是可以看到的.
假设最高的楼的位置固定,最高楼的编号为n,那么我们为了满足条件,可以在楼n的左边分x-1组,右边分y-1组,且用每
组最高的那个元素代表这一组,那么楼n的左边,从左到右,组与组之间最高的元素一定是单调递增的,且每组中的最高元
素一定排在该组的最左边,每组中的其它元素可以任意排列(相当于这个组中所有元素的环排列)。右边反之亦然。
然后,可以这样考虑这个问题,最高的那个楼左边一定有x-1个组,右边一定有y-1个组,且每组是一个环排列,这就引出
了第一类Stirling数(
个人分成
组,每组内再按特定顺序围圈的分组方法的数目)。
我们可以先把n-1个元素分成x-1+y-1组,然后每组内部做环排列。再在所有组中选取x-1组放到楼n的左边。所以答案是
ans(n, f, b) = C[f + b - 2][f - 1] * S[n - 1][f + b - 2];
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std; #define mod 1000000007
const int maxn = + ;
LL c[maxn][maxn], s[maxn][maxn]; //第一类Stirling数s(p,k)的实际意义是:将p个物体排成k个非空循环排列的方法数
void init() { //第一类斯特灵数通项公式 : S[n][k]=(S[n-1][k-1]+(n-1)*S[n-1][k])
for(int i = ; i <= ; i++) {
s[i][] = ; s[i][i] = ;
for(int j = ; j < i; j++) {
s[i][j] = ((i-)*s[i-][j]+s[i-][j-]) % mod;
//考虑递推,把n个不同元素分成k个不同的环有两种转移。第一种,有可能是n−1个不同元素
//分成k−1个不同的环,当前的第n个独立成一个元素。第二种可能是n−1个不同元素已经分好了k个不同的环,当前这个可以加进去。
}
}
} void init2() { //初始化组合数
c[][] = ;
for(int i = ; i <= ; i++) {
c[i][] = ;
for(int j = ; j <= i; j++) {
c[i][j] = c[i-][j-]+c[i-][j]; //组合数可以用杨辉三角来表示,c[i][j]=它左上方的元素+它正上方的元素
if(c[i][j] >= mod) c[i][j] -= mod;
}
}
} int main() {
init();
init2();
int T; cin >> T;
while(T--) {
int n, f, b; scanf("%d%d%d", &n, &f, &b); LL ans = (f+b- <= n && f+b- >= )? c[f+b-][f-]*s[n-][f+b-]% mod : ;
//c[f+b-2][f-1]的作用就是,将已经排好顺序的(f-1)个环按从小到大的顺序挑出f-1栋楼放在左边
printf("%lld\n", ans);
}
return ;
}
2018-08-12
HDU4372-Count the Buildings【第一类Stirling数】+【组合数】的更多相关文章
- 【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(<=2000)栋楼排成一排,高度恰好是1至n且两两不同.现在从左侧看能看到f栋,从右边看能看到b栋,问有多少种可能方案. T组数据, (T<=100000) 自己只想出了用DP搞 发 ...
- HDU 4372 Count the Buildings——第一类斯特林数
题目大意:n幢楼,从左边能看见f幢楼,右边能看见b幢楼 楼高是1~n的排列. 问楼的可能情况 把握看到楼的本质! 最高的一定能看见! 计数问题要向组合数学或者dp靠拢.但是这个题询问又很多,难以dp ...
- HDU4372 Count the Buildings —— 组合数 + 第一类斯特林数
题目链接:https://vjudge.net/problem/HDU-4372 Count the Buildings Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 4372 Count the Buildings:第一类Stirling数
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4372 题意: 有n栋高楼横着排成一排,各自的高度为1到n的一个排列. 从左边看可以看到f栋楼,从右边看 ...
- [Hdu4372] Count the Buildings
[Hdu4372] Count the Buildings Description There are N buildings standing in a straight line in the C ...
- 自然数幂和——第一类Stirling数和第二类Stirling数
第一类Stirling数 首先设 $$S_k(n)=\sum_{i=0}^ni^k$$ 根据第一类斯特林数的定义(P是排列数,C是组合数,s是Stirling) $$C_n^k={P_n^k\over ...
- hdu 4372 第一类stirling数的应用/。。。好题
/** 大意: 给定一系列楼房,都在一条水平线上,高度从1到n,从左侧看能看到f个, 从右侧看,能看到b个,问有多少种这样的序列.. 思路: 因为肯定能看到最高的,,那我们先假定最高的楼房位置确定,那 ...
- HDU 3625 Examining the Rooms:第一类stirling数
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3625 题意: 有n个房间,每个房间里放着一把钥匙,对应能开1到n号房间的门. 除了1号门,你可以踹开任 ...
随机推荐
- $Miller Rabin$总结
\(Miller Rabin\)总结: 这是一个很高效的判断质数的方法,可以在用\(O(logn)\) 的复杂度快速判断一个数是否是质数.它运用了费马小定理和二次探测定理这两个筛质数效率极高的方法. ...
- split('\r\n')
'\r'是回车,'\n'是换行,前者使光标到行首,后者使光标下移一格.通常用的Enter是两个加起来. 实际我的脚本读取FTP的列表,如果用的split("\r\n"),可以获得正 ...
- 内置函数id,返回内存地址
a = 2 def b(): a = 3 print id(a) class c(): def __init__(self): print id(c) d =c() print id(d) print ...
- python - 数据描述符(class 内置 get/set/delete方法 )
数据描述符(class 内置 get/set/del方法 ): # 什么是描述符 # 官方的定义:描述符是一种具有“捆绑行为”的对象属性.访问(获取.设置和删除)它的属性时,实际是调用特殊的方法(_g ...
- Android如何降低service被杀死概率
http://www.jianshu.com/p/06a1a434e057 http://www.cnblogs.com/ylligang/articles/2665181.html Android应 ...
- UML入门[转]
访问权限控制 class Dummy { - private field1 # protected field2 ~ package method1() + public method2() } Al ...
- WPF复制异常问题(OpenClipboard 失败 (异常来自 HRESULT:0x800401D0 (CLIPBRD_E_CANT_OPEN)))
最近在维护WPF系统的时候发现的问题,刚刚开始自己的电脑都不能重现,后面写日志跟踪才发现问题的所在.问题主要是由于:1. 在程序访问剪切板的时候,有其他程序正在占用剪切板,导致自己的程序无法访问, ...
- WPF开发中的多线程的问题
今天帮助同事做了一个WPF版的多线程demo,分享给大家. 要实现的问题就是非主线程thread1 去后台不停的取新数据,当有新数据的时候就会展示到前台. 我给他做的demo实现一个按秒的计数器,随着 ...
- centos 设置定时任务执行指定脚本的方法
vim /etc/crontab SHELL=/bin/bashPATH=/sbin:/bin:/usr/sbin:/usr/binMAILTO=rootHOME=/ # For details se ...
- ES系列十、ES常用查询API
1.term查询 { "query": { "term": { "title": "crime" } } } 1.1.指 ...