第一类斯特林数 First Kind of Stirling Number

50 篇文章 0 订阅
26 篇文章 0 订阅

 

题目描述

有n个高度分别为1到n的人,从前到后站成一列,站在前面的人会挡住后面比他矮的人。现从前面一共能看见m个人,请问有多少种可能的站法

输入格式

第一行两个整数n,m含义如图所述

输出格式

一行一个整数,为答案模1e9+7的值

数据范围

1 \leq m \leq n \leq 1000

时间限制1s,空间限制:512M

样例1

Input

3 2

Output

3

样例1解释

一共有132、231、213三种排法使得从前面能看见恰好两个人

样例2

Input

1000 500

Output

761367694

 

先打个表看一下

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1e3+2;
const int inf = 0x3f3f3f3f;
ll n, m;
int a[maxn], dp[maxn], q[maxn];
int main() {
	//cin>> n >> m;
	for (int n = 1; n <= 10; n++){
		for (int m = 1; m <= n; m++){
			for (int i = 0; i < n;i++) a[i] = i + 1;
			int ans = 0;
			do{
				int las = 0;
				for (int i = 0; i < n; i++){
					if (a[i] > las) dp[i] = dp[i - 1] + 1, las = a[i];
					else dp[i] = dp[i - 1];
				}
				if (dp[n - 1] == m) ans++;
			}while (next_permutation(a, a+n));
			printf("%d\t", ans);
		}
		printf("\n");
	}
	return 0;
} 

发现是第一类斯特林数

可以理解为n个元素,分成m组,每组把最大的站最前面,然后把这m组按站的最前面的身高由小到大排列,符合第一类斯特林数的使用条件

#include<bits/stdc++.h>
using namespace std;
#define RI register int
typedef long long ll;
const int N=1005;
const long long M = 1e9 + 7;
int n,A,B,ans,a[18][N],rev[N],m,G;
long long mod;
const int maxn = 1005;
ll Stirling[maxn][maxn], fac[maxn] = {1};
void init() {
	for(ll i = 1; i < maxn; i++)
		fac[i] = fac[i - 1] * i % M;
	Stirling[0][0] = 0;
	Stirling[1][1] = 1;
	for(ll i = 2; i < maxn; i++) {
		for(ll j = 1; j <= i; j++) {
			Stirling[i][j] = (Stirling[i - 1][j - 1] % M + (i - 1) * Stirling[i - 1][j] % M +M) % M;
		}
	}
}
signed main(){
	scanf("%lld%lld", &n, &m);
	init();
	cout << Stirling[n][m] % M << endl;
}

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值