Robot HDU - 5673

原题链接

考察:卡特兰数

错误思路:

        将答案当成卡特兰数的前缀和.这种答案是到达i点后,机器人完全不动,但此时可能步数还未用完

正确思路:

       机器人向右是卡特兰数的向右,机器人向左是卡特兰数的向上.这就是模拟进出栈,y=x上方代表出栈数>入栈数.但这里我们还需要计数不走的方法数

       设我们向右走了a步,总共n步.那么不走n-2*a步.那么不走的方案就是Cn-2*a2n 

       for循环枚举a的大小

 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 typedef long long ll;
 6 const int N = 1000010,mod = 1000000007;
 7 ll f[N],fact[N],infact[N],ans[N];
 8 ll qsm(ll a,ll k,ll q)
 9 {
10     ll res = 1;
11     while(k)
12     {
13         if(k&1) res = res*a%q;
14         a = a*a%q;
15         k>>=1; 
16     }
17     return res;
18 }
19 void inits(int n)
20 {
21     fact[0] = infact[0] = f[1] = f[0] = 1;
22     for(int i=1;i<=n+1;i++)
23     {
24         fact[i] = fact[i-1]*i%mod;
25         infact[i] = infact[i-1]*qsm(i,mod-2,mod)%mod;
26     }
27     for(int i=2;i<=n/2;i++)
28         f[i] = f[i-1]*(4*i-2)%mod*qsm(i+1,mod-2,mod)%mod;
29 }
30 ll C(int n,int y)
31 {
32     if(!y) return 1;
33     ll res = fact[n]*infact[y]%mod*infact[n-y]%mod;
34     return res;
35 }
36 int main()
37 {
38     int T;
39     scanf("%d,",&T);
40     inits(N-10);
41     while(T--)
42     {
43         int n; scanf("%d",&n);
44         if(ans[n]) { printf("%lld\n",ans[n]); continue; } 
45         for(int i=0;2*i<=n;i++)
46             ans[n] = (ans[n]+ f[i]*C(n,2*i)%mod)%mod;
47         printf("%lld\n",ans[n]);
48     }
49     return 0;
50 }

 

posted @ 2021-01-30 00:10  acmloser  阅读(54)  评论(0编辑  收藏  举报