早期作品,不喜轻喷。

LG传送门

组合数与斯特林数的基本应用。

组合数

大家应该都熟悉它的表达式,但我们这里使用它的递推式会更加方便,下面推导组合数的递推式。设\(\binom{n}{m}\)表示在\(n\)个元素中取\(m\)个的方案数,那么如果我们考虑第\(n\)个元素取或不取:取的情况就要在剩下的\(n-1\)个元素中取\(m-1\)个;不取的情况就要在剩下的\(n-1\)个元素中取\(m\)个。由此得到递推式:

\(\qquad \binom{n}{m}=\binom{n-1}{m-1}+\binom{n-1}{m}\)

斯特林数

准确地说是第一类斯特林数,通常用中括号表示,形如\([^{\,n}_{m}]\),表示\(n\)个人坐\(m\)张圆桌(没有空桌)的方案个数,我们也只需要考虑递推式。考虑第\(n\)个人单独坐一张桌子或坐到已经有人的桌子上:如果单独坐一张桌子,前面的\(n-1\)就要坐\(m-1\)张桌子;如果坐到已经有人的桌子上,就先让\(n-1\)个人坐\(m\)张桌子,第\(n\)个人可以坐到之前\(n-1\)个人中任意一个人的左边(其实说右边也无所谓,因为人们坐的是圆桌,这样考虑是为了不重不漏地包含所有的情况),这样我们就可以得到递推式:

\(\qquad [^{\,n}_{m}]=[^{\,n-1}_{m-1}]+(n-1)*[^{n-1}_{\,\,\,m}]\)

下面进入正题

首先,高度为\(n\)的建筑是肯定不会被挡住的,可以把它作为一个分水岭,在它左边的被左边的建筑挡住,在它右边的被右边的建筑挡住。

由此我们可以把所有的建筑分成\(A+B-1\)个部分,每个部分由这个部分最高的建筑和被他所挡住的建筑组成,高\(n\)的建筑单独构成一个部分。

那么我们就可以把除了\(n\)以外的\(n-1\)个建筑放到\(A+B-2\)个圆桌上(\(n\)独坐一个桌),这时就是一个斯特林数。

对于每个圆桌上的建筑,构成了一个圆排列,但由于必须有一个最高的建筑挡住其他的建筑,这个圆排列的起始端就确定了,可以不重不漏地代表一个之前提到的部分。

对于每一个这样的部分,我们只需考虑它是放在\(n\)的左边还是右边,因此答案再乘上一个组合数就可以了。

答案就是:

\(\qquad [^{\,\,\,\,\,\,n-1}_{A+B-2}]*\binom{A+B-2}{A-1}\)

我们只需要利用递推式,就可以\(O(A*n)\)的求出我们所需的斯特林数,\(O(A^2)\)的求出需要的组合数。

代码实现

#include<cstdio>
#define R register
#define L long long
#define S 50000
#define N 200
using namespace std;
const int mod=1e9+7;
L s[S+10][N+10],c[N+10][N+10];
inline int read(){
R int f=0; R char ch=getchar();
while(ch<48||ch>57) ch=getchar();
while(ch>47&&ch<58) f=(f<<3)+(f<<1)+(ch^48),ch=getchar();
return f;
}
int main(){
R int t=read(),n,a,b,i,j;
s[0][0]=s[1][1]=1;
for(i=2;i<=S;++i) s[i][1]=s[i-1][1]*(i-1);
for(i=0;i<=N;++i) c[i][0]=1;
for(i=2;i<=S;++i)
for(j=1;j<=N&&j<=i;++j)
s[i][j]=(s[i-1][j-1]+s[i-1][j]*(i-1))%mod;//斯特林数递推式
for(i=1;i<=N;++i)
for(j=1;j<=N>>1&&j<=i;++j)
c[i][j]=(c[i-1][j-1]+c[i-1][j])%mod;//组合数递推式
while(t--){
n=read(),a=read(),b=read();
printf("%lld\n",s[n-1][a+b-2]*c[a+b-2][a-1]%mod);
}
return 0;
}

我在文中用的斯特林数(中括号)是靠上标下标表示的,效果可能不太好,如果有哪位大佬知道怎么打这种中括号,请在评论区里留言,谢谢!

[FJOI2016]建筑师 斯特林数的更多相关文章

  1. Luogu4609 FJOI2016建筑师(斯特林数)

    显然排列中的最大值会将排列分成所能看到的建筑不相关的两部分.对于某一边,将所能看到的建筑和其遮挡的建筑看成一个集合.显然这个集合内最高的要排在第一个,而剩下的建筑可以随便排列,这相当于一个圆排列.同时 ...

  2. 洛谷P4609 [FJOI2016]建筑师 【第一类斯特林数】

    题目链接 洛谷P4609 题解 感性理解一下: 一神带\(n\)坑 所以我们只需将除了\(n\)外的\(n - 1\)个元素分成\(A + B - 2\)个集合,每个集合选出最大的在一端,剩余进行排列 ...

  3. 洛谷P4609 [FJOI2016]建筑师(第一类斯特林数+组合数)

    题面 洛谷 题解 (图片来源于网络,侵删) 以最高的柱子\(n\)为分界线,我们将左边的一个柱子和它右边的省略号看作一个圆排列,右边的一个柱子和它左边的省略号看作一个圆排列,于是,除了中间的最高的柱子 ...

  4. P4609 [FJOI2016]建筑师(第一类斯特林数)

    传送门 没想到连黑题都会有双倍经验的 其实这题本质上是和CF960G Bandit Blues一样的,不过那里是要用分治FFT预处理第一类斯特林数,这里直接打表预处理第一类斯特林数就可以了 //min ...

  5. LUOGU P4609 [FJOI2016]建筑师(第一类斯特林数)

    传送门 解题思路 好神仙的思路,首先一种排列中按照最高点将左右分开,那么就是要在左边选出\(a-1\)个,右边选出\(b-1\)一个,这个如何计算呢?考虑第一类斯特林数,第一类斯特林数是将\(n\)个 ...

  6. 【Luogu4609】建筑师(第一类斯特林数,组合数学)

    [Luogu4609]建筑师(组合数学) 题面 洛谷 题解 首先发现整个数组一定被最高值切成左右两半,因此除去最高值之后在左右分开考虑. 考虑一个暴力\(dp\) ,设\(f[i][j]\)表示用了\ ...

  7. CF960G Bandit Blues 第一类斯特林数、NTT、分治/倍增

    传送门 弱化版:FJOI2016 建筑师 由上面一题得到我们需要求的是\(\begin{bmatrix} N - 1 \\ A + B - 2 \end{bmatrix} \times \binom ...

  8. 【LG4609】[FJOI2016]建筑师

    [LG4609][FJOI2016]建筑师 题面 洛谷 题解 (图片来源于网络) 我们将每个柱子和他右边的省略号看作一个集合 则图中共有\(a+b-2\)个集合 而原来的元素中有\(n-1\)个(除去 ...

  9. [洛谷P4609] [FJOI2016]建筑师

    洛谷题目链接:[FJOI2016]建筑师 题目描述 小 Z 是一个很有名的建筑师,有一天他接到了一个很奇怪的任务:在数轴上建 \(n\) 个建筑,每个建筑的高度是 \(1\) 到 \(n\) 之间的一 ...

随机推荐

  1. 测试用例组合--PICT

    测试用例组合 一原理 1.配对组合原理(两两组合原理),应用工具PICT自动输出组合 name=a,b value=1,2 key=m,n 如果自己组合那么有2*2*2=8条用例 a1m a2m a1 ...

  2. springboot项目用gradle打jar包

    C:\1_work_files\workspace_sts\HR\psn\build\libs

  3. 利用JDK自带工具keyTool生成安全证书

    前言:说一下最近做的工作,主要利用iText给网页中生成好的html报表转化为pdf格式的文件,并且在其中加入水印,数字签名等等,这部分主要介绍安全证书的目的就是为了做数字签名部分用的. 下面利用jd ...

  4. 利用maven开发springMVC项目——开发环境搭建(版本错误解决)

    申明:部分内容参见别人的博客,没有任何的商业用途,只是作为自己学习使用.(大佬博客) 一.相关环境 - eclipse :eclipse-jee-oxygen-3-win32-x86_64(下载地址) ...

  5. 如何求出数组中最小(或者最大)的k个数(least k问题)

    输入n个整数,如何求出其中最小的k个数? 解法1. 当然最直观的思路是将数组排序,然后就可以找出其中最小的k个数了,时间复杂度以快速排序为例,是O(nlogn): 解法2. 借助划分(Partitio ...

  6. CC2640R2F&TI-RTOS 拿到 TI CC2640R2F 开发板 第四件事就是 修改第三件事信号量超时改为 事件 超时,并增加 事件控制 ,用于控制LED 闪烁时间或者关闭

    /* * data_process.c * * Created on: 2018年7月5日 * Author: admin */ #include "board_led.h" #i ...

  7. Android开发之自己定义TabHost文字及背景(源码分享)

    使用TabHost 能够在一个屏幕间进行不同版面的切换,而系统自带的tabhost界面较为朴素,我们应该怎样进行自己定义改动优化呢 MainActivity的源码 package com.dream. ...

  8. JDBC—执行sql语句的通用方法

    /* * 执行 sql的方法集 * delete,insert into ,update */ public static void update(String sql){ Connection co ...

  9. TCL-事务

    一.含义事务:一条或多条sql语句组成一个执行单位,一组sql语句要么都执行要么都不执行二.特点(ACID)A 原子性:一个事务是不可再分割的整体,要么都执行要么都不执行C 一致性:一个事务可以使数据 ...

  10. mysql 5.7设置密码无效

    我现在MySQL的版本时8.0.12,以前一直没有给MySQL设置密码. 今天因为需要,给MySQL设置,密码,但是上网搜了好久.....命令都不对.最后搜到csdn的Bpazy大佬的博客.他使用5. ...