洛谷P4609 [FJOI2016] 建筑师题解 第一类斯特林数

P4609 [FJOI2016] 建筑师 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

题解: 

        最大的那一个数肯定会左右都能看见n的左边能看见a-1个,右边能看见b-1个

把每个能看见的建筑与其后面的数看成一个组合,每个组是一个圆,因为每个组(这个组的建筑个数为)的排列数为(n-1)!. 问题转化为n-1个数划分为a+b-2个圆排列,因为对于左边a-1个圆,自动为从小到大排序,因此不用考虑左边这些组的排列,只有一个排列.  因此答案为stir[n-1][a+b-2]*C[a+b-2][a-1]

AC代码

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
const int mod=1e9 + 7, N = 5e4+10, M = 210; 
int main(){
	vector<vector<int> > C(M,vector<int>(M)), stir(N,vector<int>(M));
	stir[0][0] = 1,C[0][0] = 1;
	for(int i=1;i<N;i++){
		for(int j=1;j<=i&&j<M;j++)stir[i][j] = (1ll*stir[i-1][j-1] + (i-1ll) * stir[i-1][j]%mod)%mod;
	}
	for(int i=1;i < M; i++){
		C[i][0] = 1;
		for(int j = 1; j <= i; j++) C[i][j] = (1ll * C[i - 1][j] + C[i - 1][j - 1])%mod;
	}
	int T;
	cin >> T;
	while(T--){
		int n, A, B;
		cin >> n >> A >> B;
		cout << 1ll * stir[n - 1][A + B - 2] * C[A + B - 2][A - 1] % mod << endl;
	}
	
}

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值