Description
zzy今天刚买了两个水瓢A和B,容量都是为1升,童心未泯的他打算用这个水瓢来玩游戏。
首先zzy准备了一个容量可看作无穷大的水缸,刚开始水缸是空的,然后用水瓢A往水缸里加水,用水瓢B把水缸里的水舀出去,当使用 水瓢B把水舀出去时水缸里必须要至少有1升的水。这样子使用N次水瓢A,也使用N次水瓢B,最后水缸会依旧空的。
Input
输入有多个例子,直到文件结束。
每个例子仅含一个数N(0<N<=10000),表示你必须使用N次A水瓢和N次B水瓢。
Output
对于每个例子,请输出一个数,表示一共有多少种正确的舀水方式使得舀水过程中 使用B水瓢时水缸里总会有足够的水。
(由于数字比较大,输出的答案模1000000007)
Sample Input
12
Sample Output
12
通过找规律发现,方案数是一种叫做 Catalan 数的计数数列,很玄乎,现在还没掌握它的由来,
Cantalan递推公式:
F(n+1) = (4*n-6)/n * F(n).
代码:
#include<iostream>
#include<cstdio>
using namespace std;
#define LL long long
const LL MOD=1000000007;
LL Cata[10050];
void gcd(LL a,LL b,LL& d,LL &x,LL &y)
{
if(!b){d=a; x=1;y=0; }
else {gcd(b,a%b,d,y,x); y-=x*(a/b); }
}
LL inv(LL a,LL n) //a在模n下的逆元
{
LL d,x,y;
gcd(a,n,d,x,y);
return d==1?(x+n)%n:-1;
}
int main()
{
Cata[2]=1; Cata[3]=1;
for(int i=3;i<10030;i++){
Cata[i+1]=(((4*i-6)*Cata[i])%MOD*inv(i,MOD))%MOD;
}
int N;
//for(N=1;N<=100;N++)
while(scanf("%d",&N)!=EOF)
{
printf("%lld\n",Cata[N+2]);
}
return 0;
}