1120 機器人走方格 V3
阿新 • • 發佈:2018-12-24
N * N的方格,從左上到右下畫一條線。一個機器人從左上走到右下,只能向右或向下走。並要求只能在這條線的上面或下面走,不能穿越這條線,有多少種不同的走法?由於方法數量可能很大,只需要輸出Mod 10007的結果。
Input
輸入一個數N(2 <= N <= 10^9)。
Output
輸出走法的數量 Mod 10007。
Input示例
4
Output示例
10
思路:
卡特蘭數。計算時用到lucas定理。
用invf[i]=invf[i+1]*(i+1)%p這個公式反遞推得到1!~n!的逆元。
#include <cstdio> #include <cstdlib> #include <algorithm> using namespace std; const int MOD = 10007; int fac[MOD + 5]; int inv[MOD + 5]; int QPow(int x, int n) { int ret = 1; int tmp = x % MOD; while (n) { if (n & 1) { ret = (ret * tmp) % MOD; } tmp = tmp * tmp % MOD; n >>= 1; } return ret; } void init() { fac[0] = 1; for (int i = 1; i < MOD; i++) { fac[i] = fac[i - 1] * i % MOD; } inv[MOD - 1] = QPow(fac[MOD - 1], MOD - 2); for (int i = MOD - 2; i >= 0; i--) { inv[i] = inv[i + 1] * (i + 1) % MOD; } } inline int C(int n, int m) { if (n < m) { return 0; } return fac[n] * inv[m] % MOD * inv[n - m] % MOD; } int lucas(int n, int m) { return m == 0 ? 1 : C(n % MOD, m % MOD) * lucas(n / MOD, m / MOD) % MOD; } int main() { init(); int n; scanf("%d", &n); n--; printf("%d\n", (lucas(n << 1, n) + MOD - lucas(n << 1, n - 1)) % MOD * 2 % MOD); return 0; }