题解:P1044 [NOIP 2003 普及组] 栈

· · 题解

提示

我们可以计算多个不同的 n,通过观察找规律可得,这道题的答案符合卡特兰数的规律。

卡特兰数

卡特兰数是组合数学中一种常出现于各种计数问题中的数列。

卡特兰数的前几项为(从第 0 项开始):

卡特兰数的 $C_n$ 的递推规律是: $$C_{n}=C_0C_{n-1}+C_1C_{n-2}+...+C_{n-2}C_1+C_{n-1}C_0$$。 根据上面这个递推公式,直接写代码即可。 ## 代码 ### 递推写法 ```cpp #include<bits/stdc++.h> using namespace std; typedef long long LL; LL C[25]; int main(){ int n; cin >> n; C[0] = 1; for(int i=1; i<=n; i++) for(int j=0; j<i; j++) C[i] += C[j] * C[i-j-1]; // 递推公式 cout << C[n]; } ``` ### 递归写法 ```cpp #include<bits/stdc++.h> using namespace std; typedef long long LL; LL C(int x){ if(x == 0) return 1; LL ans = 0; for(int i=0; i<x; i++) ans += C(i) * C(x-i-1); // 递推公式 return ans; } int main(){ int n; cin >> n; cout << C(n); } ``` ## 打表 当然,在我们知道答案的规律之后,也可以在网上搜索卡特兰数的前几项,然后直接**打表**得到答案。 ```cpp #include<bits/stdc++.h> using namespace std; typedef long long LL; LL ans[] = {1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700}; // 刚好到第 18 项 int main(){ int n; cin >> n; cout << ans[n]; } ```