Scoop Water

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值