先推荐一个关于卡特兰数的博客:http://blog.csdn.net/hackbuteer1/article/details/7450250

  卡特兰数一个应用就是,卡特兰数的第n项表示,现在进栈和出栈的次数都是n次,问最后栈空的合法序列的个数。其他例子见上面这个博客。

  那么关于这个题目,我们先选出i次右移的(相当于进栈)次数,i次左移的(相当于出栈)次数,那么当前对答案做出的贡献就是C(n,2*i)*cat[i],枚举所有的i计算出答案即可。

  代码如下:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <string.h>
 4 using namespace std;
 5 typedef long long ll;
 6 const int N = 1000000 + 5;
 7 const int mod = (int)1e9 + 7;
 8 
 9 int inv[N],cat[N],C[N];
10 
11 void init()
12 {
13     inv[1] = 1;
14     for(int i=2;i<N;i++) inv[i] = (mod-mod/i) * 1LL * inv[mod % i] % mod;
15     
16     cat[0] = cat[1] = 1;
17     for(int i=2;i<=N/2;i++) cat[i] = 1LL* cat[i-1] * (4*i-2) % mod * inv[i+1] % mod;
18 }
19 
20 int main()
21 {
22     init();
23     int T;scanf("%d",&T);
24     while(T--)
25     {
26         int n;
27         scanf("%d",&n);
28         int ans = 0;
29         C[0] = 1; // C(n,0) = 1;
30         for(int i=1;i<=n;i++) C[i] = (ll)C[i-1] * (n-(i-1)) % mod * inv[i] % mod; // O(n)递推组合数C(n,i)
31         for(int i=0;i<=n/2;i++) ans = ((ans + (ll)C[i*2] * cat[i] % mod) % mod + mod) % mod;
32         printf("%d\n",ans);
33     }
34     return 0;
35 }