You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
1.7 KiB

2 years ago
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
const int N = 110;
int f[N];
int qmi(int a, int k, int p) {
int res = 1;
while (k) {
if (k & 1) res = (LL)res * a % p;
a = (LL)a * a % p;
k >>= 1;
}
return res;
}
int C(int a, int b, int p) {
if (a < b) return 0;
int down = 1, up = 1;
for (int i = a, j = 1; j <= b; i--, j++) {
up = (LL)up * i % p;
down = (LL)down * j % p;
}
return (LL)up * qmi(down, p - 2, p) % p;
}
//卡特兰数的前几项为1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786,208012
int main() {
//目标求出卡特兰数的前12位
//公式法计算I
//方法1:f(n)=C(n,2n)-C(n-1,2n)
for (int i = 1; i <= 12; i++)
cout << C(2 * i, i, mod) - C(2 * i, i - 1, mod) << " ";
cout << endl;
//公式法计算II
//方法2C(n,2n)/(n+1)
for (int i = 1; i <= 12; i++)
cout << C(2 * i, i, mod) / (i + 1) << " ";
cout << endl;
//递推法计算I
//方法3f(n)=(4n-2)/(n+1)*f(n-1)
f[0] = 1;
for (int i = 1; i <= 12; i++) {
f[i] = (LL)f[i - 1] * (4 * i - 2) / (i + 1); //注意:这里要先乘再除,否则可能丢失精度
cout << f[i] << " ";
}
cout << endl;
//递推法计算II
//方法4 f(n)=\sum_{i=0}^{n-1}f(i)*f(n-i+1)
//要是每次都这么推,不是效率太差了吗?
memset(f, 0, sizeof f);
f[0] = 1;
for (int i = 1; i <= 12; i++) {
for (int j = 1; j <= i; j++)
f[i] += f[j - 1] * f[i - j];
cout << f[i] << " ";
}
return 0;
}