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 }