卡特兰数 斯特林数

卡特兰数\(C_{2n}^n - C_{2n}^{n-1}\)
还有常用的递推:

int main() {
    scanf("%d", &n);
    f[0] = 1, f[1] = 1;
    for(int i=2; i<=n; i++) {
        for(int j=0; j<i; j++) {
            f[i] += f[j] * f[i-j-1];
        }
    }
    printf("%d", f[n]);
    return 0;
}

貌似很多题都是第0项为1,第一项为1,第二项为2,第三项为5这样的

第一类斯特林数
\(S(n,k) = (n-1)*S(n-1,k) + S(n-1,k-1)\)

第二类斯特林数
\(S(n,k) = k*S(n-1,k) + S(n-1,k-1)\)
\(S(n,1) = 1 \ \ (n \geq1 )\)
\(S(n,n) = 1,S(n,0)=0\)
对于第二类斯特林数公式的推导:
若第n个元素单独成一个集合,则有方案数\(S(n-1,k-1)\)
若n和别的元素成一个集合,那么n可以放到k个集合中\(k*S(n-1,k)\)

第二类斯特林数,可以求出将n个元素的集合拆分为k个的非空集合的方案数(相当于把n个不同的小球放入m个不可区分,一模一样的盒子里)

例如,将6本不同的书分为三组,求方案数
答案是S(6,3),但我们还可以用别的方法做一下这道题
根据“先分组后分配”的思路,可以分为1,1,4;2,2,2;1,2,3三种情况
对于每种情况去重:
1,1,4:\(C_6^4=C_6^2=15\),分完四本书,剩下的两本自成一组(不用再除以\(A_2^2\)了)

如果你不信服的话,从另一个角度可以导出一样的式子:\(\frac{C_6^4C_2^1}{A_2^2} = C_6^4\)(如果两个式子在数值上相同,那么这两个式子各自的组合意义可能是解决某个问题的两种思路
为什么要除以\(A_2^2\)?假设有A书和B书,分为两组(分组为:1,1),用\(C_2^1\)来算,是两种方案吗?A B 和 B A是没有差别的,所以只有一种方案。我们只是分组,而这里组和组是一样的,就像两个一模一样的盒子

2,2,2:同上,\(\frac{C_6^2C_4^2}{A_3^3} = 15\)

1,2,3:\(C_6^3C_3^2 = 60\)

一共90种方案,而第二类斯特林数可以递推求出:
x
1: 1
2: 1 1
3: 1 3 1
4: 1 7 6 1
5: 1 15 25 10 1
6: 1 31 90 65 15 1
7: 1 63 301 350 140 21 1
8: 1 127 966 1701 1050 266 28 1
9: 1 255 3025 7770 6951 2646 462 36 1
10: 1 511 9330 34105 42525 22827 5880 750 45 1
可得S(6,3) = 90

递推程序(要是有错的话,请在评论区指导一下我。。。)

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = 3000 + 10;
int s[MAXN][MAXN],n;
int main() {
    scanf("%d", &n);
    for(int i=1; i<=n; i++) {
        s[i][1] = s[i][i] = 1;
        for(int j=1; j<i; j++) {
            s[i][j] = j * s[i-1][j] + s[i-1][j-1];
        }
    }
    printf("x\n");
    for(int i=1; i<=n; i++) {
        printf("%d: ",i);
        for(int j=1; j<=i; j++) {
            printf("%d ", s[i][j]);
        }
        puts("");
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Zolrk/p/9786232.html

时间: 2024-10-13 15:25:23

卡特兰数 斯特林数的相关文章

HDU3625(SummerTrainingDay05-N 第一类斯特林数)

Examining the Rooms Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1661    Accepted Submission(s): 1015 Problem Description A murder happened in the hotel. As the best detective in the town, yo

Gym 101147G 第二类斯特林数

大致题意: n个孩子,k场比赛,每个孩子至少参加一场比赛,且每场比赛只能由一个孩子参加.问有多少种分配方式. 分析: k>n,就无法分配了. k<=n.把n分成k堆的方案数乘以n的阶乘.N分成k堆得方案数即第二类斯特林数 http://blog.csdn.net/acdreamers/article/details/8521134 #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll

hdu 4041 2011北京赛区网络赛F 组合数+斯特林数 ***

插板法基础知识 斯特林数见百科 1 #include<iostream> 2 #include<cmath> 3 #include<cstdio> 4 #include<cstring> 5 #define LL long long 6 #define eps 1e-7 7 #define MOD 1000000007 8 using namespace std; 9 int c[2001][2001]={1},stir2[1005][1005]={1};

hdu 3625 第一类斯特林数

题目链接:click here Examining the Rooms Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1146    Accepted Submission(s): 689 Problem Description A murder happened in the hotel. As the best detective

Light OJ 1236 Race 第二类斯特林数

第二类斯特林数 n 匹马 分成1 2 3... n组 每一组就是相同排名 没有先后 然后组与组之间是有顺序的 在乘以组数的阶乘 #include <cstdio> #include <cstring> using namespace std; int dp[1010][1010]; int a[1010]; int main() { a[0] = 1; dp[0][0] = 1; for(int i = 1; i <= 1000; i++) { dp[i][0] = 0; d

HDU 4045 Machine scheduling (组合数学-斯特林数,组合数学-排列组合)

Machine scheduling Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1000    Accepted Submission(s): 363 Problem Description A Baidu's engineer needs to analyze and process large amount of data o

poj 3088 斯特林数

第一类Stirling数是有正负的,其绝对值是个元素的项目分作个环排列的方法数目.常用的表示方法有. 换个较生活化的说法,就是有个人分成组,每组内再按特定顺序围圈的分组方法的数目.例如: {A,B},{C,D} {A,C},{B,D} {A,D},{B,C} {A},{B,C,D} {A},{B,D,C} {B},{A,C,D} {B},{A,D,C} {C},{A,B,D} {C},{A,D,B} {D},{A,B,C} {D},{A,C,B} 给定,有递归关系 ===============

HDU 4372 Count the Buildings(组合数学-斯特林数,组合数学-排列组合)

Count the Buildings Problem Description There are N buildings standing in a straight line in the City, numbered from 1 to N. The heights of all the buildings are distinct and between 1 and N. You can see F buildings when you standing in front of the

swjtu oj Paint Box 第二类斯特林数

http://swjtuoj.cn/problem/2382/ 题目的难点在于,用k种颜色,去染n个盒子,并且一定要用完这k种颜色,并且相邻的格子不能有相同的颜色, 打了个表发现,这个数是s(n, k) * k! s(n, k)表示求第二类斯特林数. 那么关键是怎么快速求第二类斯特林数. 这里提供一种O(k)的算法. 第二类斯特林数: #include <cstdio> #include <cstdlib> #include <cstring> #include <