题目描述:
一列火车n节车厢,依次编号为1,2,3,…,n。每节车厢有两种运动方式,进栈与出栈,问n节车厢出栈的可能排列方式有多少种。
输入格式
输入一个整数n,代表火车的车厢数。
输出格式
输出一个整数s表示n节车厢出栈的可能排列方式数量。
数据范围
1≤n≤60000
输入样例:
3
输出样例:
5
分析:
与上一题不同的是,本题只需要输出栈混洗的合法方案个数。根据递推公式可以得出n个元素栈混洗的数目为Catalan(n)个,递推公式的推导以及卡特兰数公式的推导这里不多加赘述,栈混洗序列中,除了“312”禁形外还剩h(n)=C(2n,n)/(n+1)个合法序列。所以本题的考点在于用高精度实现卡特兰数的计算,即求(2n * (2n-1)*...*(n+1)) / n! / (n+1)。
方法一:(高精度)
直接进行高精度乘法和除法运算。为了缩小中间结果的位数,采取乘一个数立刻除一个数的形式,具体表现为:乘2n除1,乘2n-1除2,乘2n-2除3...。至于为何这样每次都能够整除,可归结为:三个连续的整数连乘必然能被3整除,依次类推到n个整数连乘可以被n整除。
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
int n;
void mul(vector<int> &v,int a){
int size = v.size();
int t = 0;
for(int i = 0;i < size;i++){
v[i] = v[i] * a + t;
t = v[i] / 10;