机器人走方格

来源:互联网 发布:linux arm环境 编辑:程序博客网 时间:2024/04/30 10:30


M * N的方格,一个机器人从左上走到右下,只能向右或向下走。有多少种不同的走法?由于方法数量可能很大,只需要输出Mod 10^9 + 7的结果。

Input

第1行,2个数M,N,中间用空格隔开。(2 <= m,n <= 1000000)

Output

输出走法的数量 Mod 10^9 + 7。

Input示例

2 3

Output示例

3


思路:就是一个数学组合问题。。。( C(n-1+m-1,n-1) )

一直不知道除法取模怎么算,今天学习了一下,用到了费马小定理。

带模的除法:求 a / b = x (mod M)
只要 M 是一个素数,而且 b 不是 M 的倍数,就可以用一个逆元整数 b’,通过 a / b = a * b' (mod M),来以乘换除。
费马小定理说,对于素数 M 任意不是 M 的倍数的 b,都有:b ^ (M-1) = 1 (mod M)
于是可以拆成:b * b ^ (M-2) = 1 (mod M)
于是:a / b = a / b * (b * b ^ (M-2)) = a * (b ^ (M-2)) (mod M)
也就是说我们要求的逆元就是 b ^ (M-2) (mod M)! ——(用快速幂可以求出)


#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <string>#include <cmath>#include <set>#include <queue>#include <algorithm>#include <vector>#include <map>using namespace std;#define esp  1e-8const double PI = acos(-1.0);const double e = 2.718281828459;const int inf = 1000000005;const long long mod = 1000000007;//freopen("in.txt","r",stdin); //输入重定向,输入数据将从in.txt文件中读取//freopen("out.txt","w",stdout); //输出重定向,输出数据将保存在out.txt文件中cinlong long power(long long a, long long b){long long res = 1;while (b){if (b & 1)res = res * a % mod;b >>= 1;a = a* a % mod;}return res % mod;}long long cou(long long a, long long b){if (b > a)return 0;b = min(b, a - b);long long x = 1, y = 1;for (int i = 1; i <= b; ++i){x = x * i % mod;y = y * (a - i + 1) % mod;}//cout << x << " " << y << endl;return y * power(x, mod - 2) % mod;}int main(){long long n, m;while (cin >> n >> m)cout << cou(n + m - 2, n - 1) << endl;}



0 0
原创粉丝点击