問題は、 n番目のカタラン数modを見つけることです。m
ここで、は素数でm
はありません。これが私が試した方法のリストです:(最大)m = (10^14 + 7)
N = 10,000
- テーブルルックアップの動的計画法、遅すぎる
- カタロニア式を使用します。これも関数
ncr(2*n, n)/(n + 1)
のために十分な速度ではありませんでしたが、は素数ではないため、べき乗二乗ncr
を使用して速度を上げることはできません。m
- 事前に生成されたテーブルをハードコーディングし
Catalans
ましたが、ファイルサイズの制限のために失敗しました。 - 漸化式
C(i,k) = C(i-1,k-1) + C(i-1,k)
、これは遅すぎる
それで、私が知らないn番目のカタラン数を見つけるための他のより速いアルゴリズムがあるのだろうか?
動的計画法の使用
void generate_catalan_numbers() {
catalan[1] = 1;
for (int i = 2; i <= MAX_NUMBERS; i++) {
for (int j = 1; j <= i - 1; j++) {
catalan[i] = (catalan[i] + ((catalan[j]) * catalan[i - j]) % MODULO) % MODULO;
}
catalan[i] = catalan[i] % MODULO;
}
}
元の式を使用
ull n_choose_r(ull n, ull r) {
if (n < r)
return 0;
if (r > n/2) {
r = n - r;
}
ull result = 1;
ull common_divisor;
for (int i = 1; i <= r; ++i) {
common_divisor = gcd(result, i);
result /= common_divisor;
result *= (n - i + 1) / (i / common_divisor);
}
return result;
}
漸化式を使用する
ull n_choose_r_relation(ull n, ull r) {
for (int i = 0; i <= n + 1; ++i) {
for (int k = 0; k <= r && k <= i; ++k) {
if (k == 0 || k == i) {
ncr[i][k] = 1;
}
else {
ncr[i][k] = (ncr[i - 1][k - 1] + ncr[i - 1][k]) % MODULO;
}
}
}
return ncr[n][r];
}